sqlparser-devexpress 2.0.6 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sqlparser-devexpress",
3
- "version": "2.0.6",
3
+ "version": "2.0.7",
4
4
  "main": "src/index.js",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -139,8 +139,8 @@ function DevExpressConverter() {
139
139
  return handleInOperator(ast);
140
140
  }
141
141
 
142
- const left = convertValue(ast.field);
143
- const right = convertValue(ast.value);
142
+ const left = ast.left !== undefined ? processAstNode(ast.left) : convertValue(ast.field);
143
+ const right = ast.right !== undefined ? processAstNode(ast.right) : convertValue(ast.value);
144
144
  const comparison = [left, ast.operator.toLowerCase(), right];
145
145
 
146
146
  // Apply short-circuit evaluation if enabled
@@ -19,6 +19,21 @@ export function parse(input, variables = []) {
19
19
  const tokenizer = new Tokenizer(input);
20
20
  let currentToken = tokenizer.nextToken();
21
21
 
22
+ // // Debugging: log the tokens
23
+ // const tokens = [];
24
+ // let tempToken = currentToken;
25
+ // while (tempToken) {
26
+ // tokens.push(tempToken);
27
+ // tempToken = tokenizer.peekNextToken();
28
+ // tokenizer.nextToken();
29
+ // }
30
+
31
+ // console.log("Tokens:", tokens);
32
+
33
+ // // Reset the tokenizer
34
+ // tokenizer.reset();
35
+ // currentToken = tokenizer.nextToken();
36
+
22
37
  // Moves to the next token in the input
23
38
  function next() {
24
39
  currentToken = tokenizer.nextToken();
@@ -68,6 +83,21 @@ export function parse(input, variables = []) {
68
83
  }
69
84
 
70
85
  next(); // Consume the closing parenthesis
86
+
87
+ // Check if the next token is an operator and process it
88
+ if (currentToken && currentToken.type === "operator") {
89
+ const operator = currentToken.value;
90
+ next(); // Move to the next token after the operator
91
+ const value = parseValue(); // Parse the value after the operator
92
+
93
+ return {
94
+ type: "comparison",
95
+ left: { type: "function", name: funcName, args },
96
+ operator,
97
+ value
98
+ };
99
+ }
100
+
71
101
  return { type: "function", name: funcName, args };
72
102
  }
73
103
 
@@ -6,8 +6,8 @@ const tokenPatterns = {
6
6
  number: "\\d+", // Matches numerical values
7
7
  placeholder: "'?\\{[^}]+\\}'?", // Matches placeholders like {variable} or '{variable}'
8
8
  string: "'(?:''|[^'])*'", // Matches strings, allowing for escaped single quotes ('')
9
+ operator: "=>|<=|!=|>=|=|<>|>|<|\\bAND\\b|\\bOR\\b|\\bBETWEEN\\b|\\bIN\\b|\\bLIKE\\b|\\bIS NOT\\b|\\bNOT LIKE\\b|\\bIS\\b", // Matches SQL operators and logical keywords
9
10
  identifier: "[\\w.]+", // Matches identifiers, including table.column format
10
- operator: "(?<!\w)(=>|<=|!=|>=|=|<>|>|<|AND|OR|BETWEEN|IN|LIKE|IS)(?!\w)", // Matches SQL operators and logical keywords
11
11
  paren: "[()]", // Matches parentheses
12
12
  comma: "," // Matches commas
13
13
  };
@@ -47,12 +47,38 @@ class Tokenizer {
47
47
  // Remove surrounding single quotes from placeholders
48
48
  if (type === "placeholder") value = value.replace(/^['"]|['"]$/g, "");
49
49
 
50
+ if (type === "operator") {
51
+ const lowerValue = value.toLowerCase();
52
+
53
+ if (lowerValue === "is") {
54
+ value = "=";
55
+ } else if (lowerValue === "is not") {
56
+ value = "!=";
57
+ }
58
+ }
59
+
50
60
  return { type, value };
51
61
  }
52
62
 
53
63
  // If no valid token is found, throw an error with the remaining input for debugging
54
64
  throw new Error(`Unexpected token at: ${this.input.slice(this.index)}`);
55
65
  }
66
+
67
+ peekNextToken() {
68
+ if (this.index >= this.input.length) return null;
69
+
70
+ const savedIndex = this.index; // Save current index
71
+ try {
72
+ return this.nextToken(); // Get next token
73
+ } finally {
74
+ this.index = savedIndex; // Restore index
75
+ }
76
+ }
77
+
78
+ reset() {
79
+ this.index = 0; // Reset index to the beginning of the input
80
+ }
81
+
56
82
  }
57
83
 
58
84
  export { Tokenizer };
package/src/index.js CHANGED
@@ -38,6 +38,10 @@ export function convertAstToDevextreme(ast, variables, state) {
38
38
  // Example usage
39
39
  // const devExpressFilter = parseFilterString("((ISNULL({0}, 0) = 0 AND CompanyID = {1}) OR CompanyID IS NULL) OR BranchID = {0} | [LeadDocument.BranchID] | [LeadDocument.CompanyID]", sampleResultObject);
40
40
  // const devExpressFilter = parseFilterString("FromDate <= '{TransferOutwardDocument.DocDate}' ", sampleResultObject, "TransferOutwardDocument", "789");
41
- //const devExpressFilter = convertSQLToAst("(ISNULL(IsSubdealer,0) = {LeadDocument.AllowSubDealer})");
41
+ // const devExpressFilter = parseFilterString("(RS2ID in ({SaleOrderStatusStmtGlobalRpt.StateID}) Or ({SaleOrderStatusStmtGlobalRpt.StateID} =0)) And (RS3ID in (0,{SaleOrderStatusStmtGlobalRpt.RegionID}) Or {SaleOrderStatusStmtGlobalRpt.RegionID} =0 )", sampleResultObject,);
42
42
 
43
+ // const devExpressFilter = convertSQLToAst("ISNULL(SourceID,0) = {ServiceOrderDocument.SourceID} OR ISNULL(SourceID,0) = 0");
44
+ // const devExpressFilterresult = convertAstToDevextreme(devExpressFilter.ast, devExpressFilter.variables,{'ServiceOrderDocument.SourceID': 2});
43
45
  // console.log("DevExpress Filter:", JSON.stringify(devExpressFilter, null, 2));
46
+ // console.log("DevExpress Result:", JSON.stringify(devExpressFilterresult, null, 2));
47
+
@@ -130,6 +130,22 @@ describe("Parser SQL to dx Filter Builder", () => {
130
130
  expected: [
131
131
  "FromDate", "between", ["10-10-2021", "10-10-2022"]
132
132
  ]
133
+ },
134
+ {
135
+ input: "BranchID is Null OR BranchID is not 12",
136
+ expected: [
137
+ ["BranchID", "=", null],
138
+ "or",
139
+ ["BranchID", "!=", 12]
140
+ ]
141
+ },
142
+ {
143
+ input: "ISNULL(SourceID,0) = {ServiceOrderDocument.SourceID} OR ISNULL(SourceID,0) = 0",
144
+ expected: [
145
+ ["SourceID", "=", 2],
146
+ "or",
147
+ ["SourceID", "=", 0]
148
+ ]
133
149
  }
134
150
  ];
135
151
 
@@ -193,5 +209,6 @@ const sampleData = {
193
209
  "TransferOutwardDocument.RefBranchID": 42,
194
210
  "TransferOutwardDocument.CompanyID": 7,
195
211
  "LeadDocument.BranchID": 42,
196
- "LeadDocument.CompanyID": 7
212
+ "LeadDocument.CompanyID": 7,
213
+ "ServiceOrderDocument.SourceID": 2
197
214
  };