Skip to content

Commit ee05901

Browse files
author
Robert Kesterson
committed
Revert graph change that made paramToString pure
1 parent abd1b25 commit ee05901

File tree

2 files changed

+265
-5
lines changed

2 files changed

+265
-5
lines changed

Diff for: src/graph.js

+260
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
"use strict";
2+
const redis = require("redis"),
3+
util = require("util"),
4+
ResultSet = require("./resultSet");
5+
6+
/**
7+
* RedisGraph client
8+
*/
9+
class Graph {
10+
/**
11+
* Creates a client to a specific graph running on the specific host/post
12+
* See: node_redis for more options on createClient
13+
*
14+
* @param {string} graphId the graph id
15+
* @param {string | RedisClient} [host] Redis host or node_redis client
16+
* @param {string | int} [port] Redis port
17+
* @param {ClientOpts} [options] node_redis options
18+
*/
19+
constructor(graphId, host, port, options) {
20+
this._graphId = graphId; // Graph ID
21+
this._labels = []; // List of node labels.
22+
this._relationshipTypes = []; // List of relation types.
23+
this._properties = []; // List of properties.
24+
25+
this._labelsPromise = undefined; // used as a synchronization mechanizom for labels retrival
26+
this._propertyPromise = undefined; // used as a synchronization mechanizom for property names retrival
27+
this._relationshipPromise = undefined; // used as a synchronization mechanizom for relationship types retrival
28+
29+
this._client =
30+
host instanceof redis.RedisClient
31+
? host
32+
: redis.createClient(port, host, options);
33+
this._sendCommand = util.promisify(this._client.send_command).bind(this._client);
34+
}
35+
/**
36+
* Closes the client.
37+
*/
38+
close() {
39+
this._client.quit();
40+
}
41+
42+
/**
43+
* Auxiliary function to extract string(s) data from procedures such as:
44+
* db.labels, db.propertyKeys and db.relationshipTypes
45+
* @param {ResultSet} resultSet - a procedure result set
46+
* @returns {string[]} strings array.
47+
*/
48+
_extractStrings(resultSet) {
49+
var strings = [];
50+
while (resultSet.hasNext()) {
51+
strings.push(resultSet.next().getString(0));
52+
}
53+
return strings;
54+
}
55+
56+
/**
57+
* Transforms a parameter value to string.
58+
* @param {object} paramValue
59+
* @returns {string} the string representation of paramValue.
60+
*/
61+
paramToString(paramValue) {
62+
if (paramValue == null) return "null";
63+
let paramType = typeof paramValue;
64+
if (paramType == "string") {
65+
let strValue = "";
66+
paramValue = paramValue.replace(/[\\"']/g, '\\$&');
67+
if (paramValue[0] != '"') strValue += '"';
68+
strValue += paramValue;
69+
if (!paramValue.endsWith('"') || paramValue.endsWith("\\\"")) strValue += '"';
70+
return strValue;
71+
}
72+
if (Array.isArray(paramValue)) {
73+
let stringsArr = new Array(paramValue.length);
74+
for (var i = 0; i < paramValue.length; i++) {
75+
stringsArr[i] = this.paramToString(paramValue[i]);
76+
}
77+
return ["[", stringsArr.join(", "), "]"].join("");
78+
}
79+
return paramValue;
80+
}
81+
82+
/**
83+
* Extracts parameters from dictionary into cypher parameters string.
84+
* @param {Map} params parameters dictionary.
85+
* @return {string} a cypher parameters string.
86+
*/
87+
buildParamsHeader(params) {
88+
let paramsArray = ["CYPHER"];
89+
90+
for (var key in params) {
91+
let value = this.paramToString(params[key]);
92+
paramsArray.push(`${key}=${value}`);
93+
}
94+
paramsArray.push(" ");
95+
return paramsArray.join(" ");
96+
}
97+
98+
/**
99+
* Execute a Cypher query
100+
* @async
101+
* @param {string} query Cypher query
102+
* @param {Map} [params] Parameters map
103+
* @returns {ResultSet} a promise contains a result set
104+
*/
105+
async query(query, params) {
106+
if (params) {
107+
query = this.buildParamsHeader(params) + query;
108+
}
109+
var res = await this._sendCommand("graph.QUERY", [
110+
this._graphId,
111+
query,
112+
"--compact"
113+
]);
114+
var resultSet = new ResultSet(this);
115+
return resultSet.parseResponse(res);
116+
}
117+
118+
/**
119+
* Deletes the entire graph
120+
* @async
121+
* @returns {ResultSet} a promise contains the delete operation running time statistics
122+
*/
123+
async deleteGraph() {
124+
var res = await this._sendCommand("graph.DELETE", [this._graphId]);
125+
//clear internal graph state
126+
this._labels = [];
127+
this._relationshipTypes = [];
128+
this._properties = [];
129+
var resultSet = new ResultSet(this);
130+
return resultSet.parseResponse(res);
131+
}
132+
133+
/**
134+
* Calls procedure
135+
* @param {string} procedure Procedure to call
136+
* @param {string[]} [args] Arguments to pass
137+
* @param {string[]} [y] Yield outputs
138+
* @returns {ResultSet} a promise contains the procedure result set data
139+
*/
140+
callProcedure(procedure, args = new Array(), y = new Array()) {
141+
let q = "CALL " + procedure + "(" + args.join(",") + ")" + y.join(" ");
142+
return this.query(q);
143+
}
144+
145+
/**
146+
* Retrieves all labels in graph.
147+
* @async
148+
*/
149+
async labels() {
150+
if (this._labelsPromise == undefined) {
151+
this._labelsPromise = this.callProcedure("db.labels").then(
152+
response => {
153+
return this._extractStrings(response);
154+
}
155+
);
156+
this._labels = await this._labelsPromise;
157+
this._labelsPromise = undefined;
158+
} else {
159+
await this._labelsPromise;
160+
}
161+
}
162+
163+
/**
164+
* Retrieves all relationship types in graph.
165+
* @async
166+
*/
167+
async relationshipTypes() {
168+
if (this._relationshipPromise == undefined) {
169+
this._relationshipPromise = this.callProcedure(
170+
"db.relationshipTypes"
171+
).then(response => {
172+
return this._extractStrings(response);
173+
});
174+
this._relationshipTypes = await this._relationshipPromise;
175+
this._relationshipPromise = undefined;
176+
} else {
177+
await this._relationshipPromise;
178+
}
179+
}
180+
181+
/**
182+
* Retrieves all properties in graph.
183+
* @async
184+
*/
185+
async propertyKeys() {
186+
if (this._propertyPromise == undefined) {
187+
this._propertyPromise = this.callProcedure("db.propertyKeys").then(
188+
response => {
189+
return this._extractStrings(response);
190+
}
191+
);
192+
this._properties = await this._propertyPromise;
193+
this._propertyPromise = undefined;
194+
} else {
195+
await this._propertyPromise;
196+
}
197+
}
198+
199+
/**
200+
* Retrieves label by ID.
201+
* @param {int} id internal ID of label.
202+
* @returns {string} String label.
203+
*/
204+
getLabel(id) {
205+
return this._labels[id];
206+
}
207+
208+
/**
209+
* Retrieve all the labels from the graph and returns the wanted label
210+
* @async
211+
* @param {int} id internal ID of label.
212+
* @returns {string} String label.
213+
*/
214+
async fetchAndGetLabel(id) {
215+
await this.labels();
216+
return this._labels[id];
217+
}
218+
219+
/**
220+
* Retrieves relationship type by ID.
221+
* @param {int} id internal ID of relationship type.
222+
* @return String relationship type.
223+
*/
224+
getRelationship(id) {
225+
return this._relationshipTypes[id];
226+
}
227+
228+
/**
229+
* Retrieves al the relationships types from the graph, and returns the wanted type
230+
* @async
231+
* @param {int} id internal ID of relationship type.
232+
* @returns {string} String relationship type.
233+
*/
234+
async fetchAndGetRelationship(id) {
235+
await this.relationshipTypes();
236+
return this._relationshipTypes[id];
237+
}
238+
239+
/**
240+
* Retrieves property name by ID.
241+
* @param {int} id internal ID of property.
242+
* @returns {string} String property.
243+
*/
244+
getProperty(id) {
245+
return this._properties[id];
246+
}
247+
248+
/**
249+
* Retrieves al the properties from the graph, and returns the wanted property
250+
* @async
251+
* @param {int} id internal ID of property.
252+
* @returns {string} String property.
253+
*/
254+
async fetchAndGetProperty(id) {
255+
await this.propertyKeys();
256+
return this._properties[id];
257+
}
258+
}
259+
260+
module.exports = Graph;

Diff for: src/graph.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,11 @@ export class Graph {
8585
if (paramValue == null) return "null";
8686
if (isString(paramValue)) {
8787
let strValue = "";
88-
let pv: string = `${paramValue}`;
89-
pv = pv.replace(/[\\"']/g, "\\$&");
90-
if (pv[0] != '"') strValue += '"';
91-
strValue += pv;
92-
if (!pv.endsWith('"') || pv.endsWith('\\"')) pv += '"';
88+
paramValue = paramValue.replace(/[\\"']/g, "\\$&");
89+
if (paramValue[0] != '"') strValue += '"';
90+
strValue += paramValue;
91+
if (!paramValue.endsWith('"') || paramValue.endsWith('\\"'))
92+
strValue += '"';
9393
return strValue;
9494
}
9595
if (Array.isArray(paramValue)) {

0 commit comments

Comments
 (0)