@digitalwalletcorp/sql-builder 1.6.1 → 2.1.0
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/README.md +226 -51
- package/lib/abstract-syntax-tree.d.ts +1 -1
- package/lib/abstract-syntax-tree.js +6 -6
- package/lib/abstract-syntax-tree.js.map +1 -1
- package/lib/common.d.ts +21 -0
- package/lib/common.js +35 -4
- package/lib/common.js.map +1 -1
- package/lib/sql-builder.d.ts +21 -1
- package/lib/sql-builder.js +295 -74
- package/lib/sql-builder.js.map +1 -1
- package/package.json +7 -2
- package/src/abstract-syntax-tree.ts +5 -6
- package/src/common.ts +40 -4
- package/src/sql-builder.ts +359 -87
package/README.md
CHANGED
|
@@ -2,27 +2,68 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@digitalwalletcorp/sql-builder) [](https://opensource.org/licenses/MIT) [](https://github.com/digitalwalletcorp/sql-builder/actions) [](https://codecov.io/gh/digitalwalletcorp/sql-builder)
|
|
4
4
|
|
|
5
|
-
Inspired by Java's S2Dao
|
|
5
|
+
Inspired by Java's **S2Dao its successor Doma**, this TypeScript/JavaScript library dynamically generates SQL. It embeds entity objects into SQL templates, simplifying complex query construction and enhancing readability. Ideal for flexible, type-safe SQL generation without a full ORM. It efficiently handles dynamic `WHERE` clauses, parameter binding, and looping, reducing boilerplate code.
|
|
6
6
|
|
|
7
7
|
The core mechanism involves parsing special SQL comments (`/*IF ...*/`, `/*BEGIN...*/`, etc.) in a template and generating a final query based on a provided data object.
|
|
8
8
|
|
|
9
|
-
###
|
|
9
|
+
### ⚠️ Breaking Change in IN Clause Behavior (v1 → v2)
|
|
10
|
+
|
|
11
|
+
**v2.0.0 introduces a breaking change in how arrays are rendered for `IN` clauses.**
|
|
12
|
+
|
|
13
|
+
- **v1.x behavior:** The bind array was automatically output with surrounding parentheses, so the template **did not need to include parentheses**.
|
|
14
|
+
- **v2.x behavior:** Only the array values are output. You must **include parentheses in the template** to form a valid `IN` clause.
|
|
15
|
+
|
|
16
|
+
**v1.x Example (no parentheses in template)**
|
|
17
|
+
```sql
|
|
18
|
+
SELECT *
|
|
19
|
+
FROM activity
|
|
20
|
+
WHERE project_name IN /*projectNames*/('project1')
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
const bindEntity = { projectNames: ['api', 'batch'] };
|
|
25
|
+
const sql = builder.generateSQL(template, bindEntity);
|
|
26
|
+
console.log(sql);
|
|
27
|
+
|
|
28
|
+
// Output (v1.x)
|
|
29
|
+
// project_name IN ('api','batch') ← parentheses added automatically
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**v2.x Example (parentheses required in template)**
|
|
33
|
+
```sql
|
|
34
|
+
SELECT *
|
|
35
|
+
FROM activity
|
|
36
|
+
WHERE project_name IN (/*projectNames*/'project1')
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
const bindEntity = { projectNames: ['api', 'batch'] };
|
|
41
|
+
const sql = builder.generateSQL(template, bindEntity);
|
|
42
|
+
console.log(sql);
|
|
43
|
+
|
|
44
|
+
// Output (v2.x)
|
|
45
|
+
// project_name IN ('api','batch') ← only values are inserted
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
> 💡 Tip: If you upgrade a template from v1.x to v2.x, make sure to add parentheses around any IN bind variables to avoid SQL syntax errors.
|
|
49
|
+
|
|
50
|
+
#### ✨ Features
|
|
10
51
|
|
|
11
52
|
* Dynamic Query Generation: Build complex SQL queries dynamically at runtime.
|
|
12
|
-
* Conditional Logic (`/*IF...*/`):
|
|
53
|
+
* Conditional Logic (`/*IF...*/`, `/*ELSEIF...*/`, `/*ELSE...*/`): Robust conditional branching. Support for complex `if-elseif-else` structures, including nesting.
|
|
13
54
|
* Optional Blocks (`/*BEGIN...*/`): Wrap entire clauses (like `WHERE`) that are only included if at least one inner `/*IF...*/` condition is met.
|
|
14
55
|
* Looping (`/*FOR...*/`): Generate repetitive SQL snippets by iterating over arrays in your data (e.g., for multiple `LIKE` or `OR` conditions).
|
|
15
56
|
* Simple Parameter Binding: Easily bind values from your data object into the SQL query.
|
|
16
57
|
* Zero Dependencies: A single, lightweight class with no external library requirements.
|
|
17
58
|
|
|
18
|
-
|
|
59
|
+
#### ✅ Compatibility
|
|
19
60
|
|
|
20
61
|
This library is written in pure, environment-agnostic JavaScript/TypeScript and has zero external dependencies, allowing it to run in various environments.
|
|
21
62
|
|
|
22
63
|
- ✅ **Node.js**: Designed and optimized for server-side use in any modern Node.js environment. This is the **primary and recommended** use case.
|
|
23
64
|
- ⚠️ **Browser-like Environments (Advanced)**: While technically capable of running in browsers (e.g., for use with in-browser databases like SQLite via WebAssembly), generating SQL on the client-side to be sent to a server **is a significant security risk and is strongly discouraged** in typical web applications.
|
|
24
65
|
|
|
25
|
-
|
|
66
|
+
#### 📦 Installation
|
|
26
67
|
|
|
27
68
|
```bash
|
|
28
69
|
npm install @digitalwalletcorp/sql-builder
|
|
@@ -48,8 +89,8 @@ SELECT
|
|
|
48
89
|
FROM activity
|
|
49
90
|
/*BEGIN*/WHERE
|
|
50
91
|
1 = 1
|
|
51
|
-
/*IF projectNames != null && projectNames.length*/AND project_name IN /*projectNames*/
|
|
52
|
-
/*IF statuses != null && statuses.length*/AND status IN /*statuses*/
|
|
92
|
+
/*IF projectNames != null && projectNames.length*/AND project_name IN (/*projectNames*/'project1')/*END*/
|
|
93
|
+
/*IF statuses != null && statuses.length*/AND status IN (/*statuses*/1)/*END*/
|
|
53
94
|
/*END*/
|
|
54
95
|
ORDER BY started_at DESC
|
|
55
96
|
LIMIT /*limit*/100
|
|
@@ -110,7 +151,75 @@ ORDER BY started_at DESC
|
|
|
110
151
|
LIMIT 100
|
|
111
152
|
```
|
|
112
153
|
|
|
113
|
-
##### Example 2:
|
|
154
|
+
##### Example 2: Dynamic WHERE Clause with `ELSEIF/ELSE`
|
|
155
|
+
|
|
156
|
+
**Template:**
|
|
157
|
+
|
|
158
|
+
```sql
|
|
159
|
+
SELECT
|
|
160
|
+
*
|
|
161
|
+
FROM users
|
|
162
|
+
WHERE
|
|
163
|
+
1 = 1
|
|
164
|
+
/*IF role === 'admin'*/
|
|
165
|
+
AND access_level = 99
|
|
166
|
+
/*ELSEIF role === 'editor'*/
|
|
167
|
+
AND access_level = 50
|
|
168
|
+
/*ELSE*/
|
|
169
|
+
AND access_level = 1
|
|
170
|
+
/*END*/
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Code:**
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { SQLBuilder } from '@digitalwalletcorp/sql-builder';
|
|
177
|
+
|
|
178
|
+
const builder = new SQLBuilder();
|
|
179
|
+
|
|
180
|
+
const template = `...`; // The SQL template from above
|
|
181
|
+
|
|
182
|
+
const bindEntity1 = {
|
|
183
|
+
role: 'editor'
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// SCENARIO A: Matched with ELSEIF condition
|
|
187
|
+
const sql = builder.generateSQL(template, bindEntity1);
|
|
188
|
+
console.log(sql1);
|
|
189
|
+
|
|
190
|
+
// SCENARIO B: Matched with ELSE condition
|
|
191
|
+
const bindEntity2 = {
|
|
192
|
+
role: 'read'
|
|
193
|
+
};
|
|
194
|
+
const sql2 = builder.generateSQL(template, bindEntity2);
|
|
195
|
+
console.log(sql2);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Resulting SQL:**
|
|
199
|
+
|
|
200
|
+
* SQL 1 (Scenario A)
|
|
201
|
+
|
|
202
|
+
```sql
|
|
203
|
+
SELECT
|
|
204
|
+
*
|
|
205
|
+
FROM users
|
|
206
|
+
WHERE
|
|
207
|
+
1 = 1
|
|
208
|
+
AND access_level = 50
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
* SQL 2 (Scenario B)
|
|
212
|
+
|
|
213
|
+
```sql
|
|
214
|
+
SELECT
|
|
215
|
+
*
|
|
216
|
+
FROM users
|
|
217
|
+
WHERE
|
|
218
|
+
1 = 1
|
|
219
|
+
AND access_level = 1
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
##### Example 3: FOR Loop
|
|
114
223
|
|
|
115
224
|
Use a `/*FOR...*/` block to iterate over an array and generate SQL for each item. This is useful for building multiple `LIKE` conditions.
|
|
116
225
|
|
|
@@ -190,7 +299,8 @@ If you need to use database-specific features, use `generateParameterizedSQL` wi
|
|
|
190
299
|
|
|
191
300
|
##### `generateParameterizedSQL(template: string, entity: Record<string, any>, bindType?: 'postgres' | 'mysql' | 'oracle' | 'mssql'): [string, Array<any> | Record<string, any>]`
|
|
192
301
|
|
|
193
|
-
Generates a SQL string with placeholders for prepared statements and returns
|
|
302
|
+
Generates a SQL string with placeholders for prepared statements and returns bind parameters.
|
|
303
|
+
This method prevents SQL injection for value bindings by using parameterized queries.
|
|
194
304
|
|
|
195
305
|
* `template`: The SQL template string containing S2Dao-style comments.
|
|
196
306
|
* `entity`: A data object whose properties are used for evaluating conditions (`/*IF...*/`) and binding values.
|
|
@@ -200,7 +310,7 @@ Generates a SQL string with placeholders for prepared statements and returns an
|
|
|
200
310
|
* `sql`: The generated SQL query with appropriate placeholders.
|
|
201
311
|
* `bindParams`: An array of values (for PostgreSQL/MySQL) or an object of named values (for Oracle/SQL Server) to bind to the placeholders.
|
|
202
312
|
|
|
203
|
-
##### Example
|
|
313
|
+
##### Example 4: Parameterized SQL with PostgreSQL
|
|
204
314
|
|
|
205
315
|
**Template:**
|
|
206
316
|
|
|
@@ -212,7 +322,7 @@ FROM users
|
|
|
212
322
|
/*BEGIN*/WHERE
|
|
213
323
|
1 = 1
|
|
214
324
|
/*IF userId != null*/AND user_id = /*userId*/0/*END*/
|
|
215
|
-
/*IF projectNames.length*/AND project_name IN /*projectNames*/
|
|
325
|
+
/*IF projectNames.length*/AND project_name IN (/*projectNames*/'default_project')/*END*/
|
|
216
326
|
/*END*/
|
|
217
327
|
```
|
|
218
328
|
|
|
@@ -236,7 +346,7 @@ console.log('Parameters:', params);
|
|
|
236
346
|
|
|
237
347
|
**Resulting SQL & Parameters:**
|
|
238
348
|
|
|
239
|
-
```
|
|
349
|
+
```sql
|
|
240
350
|
SQL:
|
|
241
351
|
SELECT
|
|
242
352
|
id,
|
|
@@ -251,31 +361,7 @@ Parameters:
|
|
|
251
361
|
[ 123, 'project_a', 'project_b' ]
|
|
252
362
|
```
|
|
253
363
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
When using PostgreSQL-specific features such as `ANY` with array parameters,
|
|
257
|
-
the SQL template must be written in a form that is valid PostgreSQL SQL by itself.
|
|
258
|
-
|
|
259
|
-
For example, to use `ANY` with a text array, write the array literal directly in the template.
|
|
260
|
-
The builder will replace the **entire array literal** with a single bind placeholder:
|
|
261
|
-
|
|
262
|
-
```sql
|
|
263
|
-
AND user_id = ANY (/*userIds*/ARRAY['U100','U101']::text[])
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
This will be rendered as:
|
|
267
|
-
|
|
268
|
-
```sql
|
|
269
|
-
AND user_id = ANY ($1::text[])
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
with the following bind parameters:
|
|
273
|
-
|
|
274
|
-
```typescript
|
|
275
|
-
[ ['U100', 'U101'] ]
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
##### Example 4: INSERT with NULL normalization
|
|
364
|
+
##### Example 5: INSERT with NULL normalization
|
|
279
365
|
|
|
280
366
|
**Template:**
|
|
281
367
|
|
|
@@ -328,7 +414,7 @@ console.log('Parameters2:', params2);
|
|
|
328
414
|
|
|
329
415
|
**Result:**
|
|
330
416
|
|
|
331
|
-
```
|
|
417
|
+
```sql
|
|
332
418
|
SQL1:
|
|
333
419
|
INSERT INTO users (
|
|
334
420
|
user_id,
|
|
@@ -361,10 +447,8 @@ Parameters2:
|
|
|
361
447
|
|
|
362
448
|
**Notes:**
|
|
363
449
|
|
|
364
|
-
- For both `generateSQL` and `generateParameterizedSQL`,
|
|
365
|
-
|
|
366
|
-
- This behavior is especially important for INSERT / UPDATE statements,
|
|
367
|
-
where the number of columns and values must always match.
|
|
450
|
+
- For both `generateSQL` and `generateParameterizedSQL`, `undefined` and `null` values are normalized to SQL `NULL`.
|
|
451
|
+
- This behavior is especially important for INSERT / UPDATE statements, where the number of columns and values must always match.
|
|
368
452
|
- NOT NULL constraint violations are intentionally left to the database.
|
|
369
453
|
- If you need to handle `IS NULL` conditions explicitly, you can use `/*IF */` blocks as shown below:
|
|
370
454
|
|
|
@@ -385,9 +469,11 @@ WHERE
|
|
|
385
469
|
| Tag | Syntax | Description |
|
|
386
470
|
| --- | --- | --- |
|
|
387
471
|
| IF | `/*IF condition*/ ... /*END*/` | Includes the enclosed SQL fragment only if the `condition` evaluates to a truthy value. The condition is a JavaScript expression evaluated against the `entity` object. |
|
|
388
|
-
|
|
|
472
|
+
| ELSEIF | `/*ELSEIF condition*/ ...` | Evaluates only if the preceding `IF` or `ELSEIF` was false. Must be placed inside an `IF` block. |
|
|
473
|
+
| ELSE | `/*ELSE*/ ...` | Included if all preceding `IF` and `ELSEIF` conditions in the block were false. |
|
|
474
|
+
| BEGIN | `/*BEGIN*/ ... /*END*/` | A wrapper block, typically for a `WHERE` clause. The entire block is included only if at least one inner `IF/ELSEIF/ELSE` or `FOR` block is active. This intelligently removes the `WHERE` keyword if no filters apply. |
|
|
389
475
|
| FOR | `/*FOR item:collection*/ ... /*END*/` | Iterates over the `collection` array from the `entity`. For each loop, the enclosed SQL is generated, and the current value is available as the `item` variable for binding. |
|
|
390
|
-
| Bind Variable | `/*variable*/` | Binds a value from the `entity`.
|
|
476
|
+
| Bind Variable | `/*variable*/` | Binds a value from the `entity`. Strings are quoted `'value'`, numbers are rendered as-is `123`. When the value is an array, elements are expanded into a comma-separated list. The template may contain zero or one dummy expression after a bind tag. If present, only a single SQL expression is allowed. Multiple comma-separated dummy values are not supported. |
|
|
391
477
|
| END | `/*END*/` | Marks the end of an `IF`, `BEGIN`, or `FOR` block. |
|
|
392
478
|
|
|
393
479
|
---
|
|
@@ -433,16 +519,105 @@ The `condition` inside an `/*IF ...*/` tag is evaluated as a JavaScript expressi
|
|
|
433
519
|
|
|
434
520
|
---
|
|
435
521
|
|
|
436
|
-
|
|
522
|
+
#### Vendor Dependency TIPS
|
|
437
523
|
|
|
438
|
-
|
|
524
|
+
**PostgreSQL**
|
|
439
525
|
|
|
440
|
-
|
|
526
|
+
When using PostgreSQL-specific features such as `ANY` with array parameters,
|
|
527
|
+
the SQL template must be written in a form that is valid PostgreSQL SQL by itself.
|
|
528
|
+
|
|
529
|
+
For example, to use `ANY` with a text array, write the array literal directly in the template.
|
|
530
|
+
The builder will replace the **entire array literal** with a single bind placeholder:
|
|
441
531
|
|
|
442
|
-
|
|
532
|
+
```sql
|
|
533
|
+
AND user_id = ANY (/*userIds*/ARRAY['U100','U101']::text[])
|
|
534
|
+
```
|
|
443
535
|
|
|
444
|
-
|
|
536
|
+
This will be rendered as:
|
|
445
537
|
|
|
446
|
-
|
|
538
|
+
```sql
|
|
539
|
+
AND user_id = ANY ($1::text[])
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
with the following bind parameters:
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
[ ['U100', 'U101'] ]
|
|
546
|
+
```
|
|
447
547
|
|
|
448
|
-
|
|
548
|
+
**MSSQL**
|
|
549
|
+
|
|
550
|
+
When working with a large number of values for an IN condition in SQL Server, directly expanding them into:
|
|
551
|
+
|
|
552
|
+
```sql
|
|
553
|
+
WHERE UserID IN (1, 2, 3, ..., N)
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
may lead to:
|
|
557
|
+
|
|
558
|
+
* **No Parameter Limits:** Counts as only 1 parameter regardless of array size.
|
|
559
|
+
* **Better Performance:** Avoids the overhead of parsing thousands of individual parameters.
|
|
560
|
+
* **Type Safety:** `OPENJSON` allows explicit type mapping (e.g., `INT`, `UNIQUEIDENTIFIER`).
|
|
561
|
+
|
|
562
|
+
SQL Server has a maximum limit of 2,100 parameters per RPC request. When using large IN (...) clauses via drivers like `Tedious`, each item in the list is typically treated as a separate parameter.
|
|
563
|
+
|
|
564
|
+
**Template:**
|
|
565
|
+
|
|
566
|
+
```sql
|
|
567
|
+
DECLARE @jsonUserIds NVARCHAR(MAX) = N'[/*userIds*/100]';
|
|
568
|
+
|
|
569
|
+
WITH T AS (
|
|
570
|
+
SELECT value AS UserID
|
|
571
|
+
FROM OPENJSON(@jsonUserIds)
|
|
572
|
+
)
|
|
573
|
+
SELECT
|
|
574
|
+
U.UserID,
|
|
575
|
+
U.Status,
|
|
576
|
+
U.CreatedAt,
|
|
577
|
+
U.UpdatedAt
|
|
578
|
+
FROM Users U
|
|
579
|
+
JOIN T
|
|
580
|
+
ON U.UserID = T.UserID
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
**Code:**
|
|
584
|
+
|
|
585
|
+
```typescript
|
|
586
|
+
const template = '...'; // above SQL
|
|
587
|
+
const builder = new SQLBuilder();
|
|
588
|
+
const [sql, params] = builder.generateParameterizedSQL(template, { userIds: [100, 101, 102, 103] }, 'mssql');
|
|
589
|
+
console.log(sql, params);
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
**Result:**
|
|
593
|
+
|
|
594
|
+
```sql
|
|
595
|
+
SQL:
|
|
596
|
+
DECLARE @jsonUserIds NVARCHAR(MAX) = @userIds;
|
|
597
|
+
|
|
598
|
+
WITH T AS (
|
|
599
|
+
SELECT value AS UserID
|
|
600
|
+
FROM OPENJSON(@jsonUserIds)
|
|
601
|
+
)
|
|
602
|
+
SELECT
|
|
603
|
+
U.UserID,
|
|
604
|
+
U.Status,
|
|
605
|
+
U.CreatedAt,
|
|
606
|
+
U.UpdatedAt
|
|
607
|
+
FROM Users U
|
|
608
|
+
JOIN T
|
|
609
|
+
ON U.UserID = T.UserID
|
|
610
|
+
|
|
611
|
+
Parameters:
|
|
612
|
+
{
|
|
613
|
+
userIds: '[100,101,102,103]'
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
By passing the array as a single JSON parameter and expanding it with OPENJSON, you can avoid large IN (...) lists and handle arbitrarily large collections in a clean and scalable way.
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
#### 📜 License
|
|
622
|
+
|
|
623
|
+
This project is licensed under the MIT License. See the [LICENSE](https://opensource.org/licenses/MIT) file for details.
|
|
@@ -31,7 +31,7 @@ export declare class AbstractSyntaxTree {
|
|
|
31
31
|
/**
|
|
32
32
|
* 与えられた条件文字列を構文解析し、entityに対する条件として成立するか評価する
|
|
33
33
|
*
|
|
34
|
-
* @param {string} condition
|
|
34
|
+
* @param {string} condition 'params != null && params.length > 10' のような条件
|
|
35
35
|
* @param {Record<string, any>} entity
|
|
36
36
|
* @returns {boolean}
|
|
37
37
|
*/
|
|
@@ -57,7 +57,7 @@ class AbstractSyntaxTree {
|
|
|
57
57
|
/**
|
|
58
58
|
* 与えられた条件文字列を構文解析し、entityに対する条件として成立するか評価する
|
|
59
59
|
*
|
|
60
|
-
* @param {string} condition
|
|
60
|
+
* @param {string} condition 'params != null && params.length > 10' のような条件
|
|
61
61
|
* @param {Record<string, any>} entity
|
|
62
62
|
* @returns {boolean}
|
|
63
63
|
*/
|
|
@@ -69,9 +69,8 @@ class AbstractSyntaxTree {
|
|
|
69
69
|
return result;
|
|
70
70
|
}
|
|
71
71
|
catch (error) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
throw error;
|
|
72
|
+
const enhancedMessage = `[SQLBuilder] Failed to evaluate IF condition: '/*IF ${condition}*/'. ${error.message}`;
|
|
73
|
+
throw new Error(enhancedMessage);
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
76
|
/**
|
|
@@ -252,7 +251,8 @@ class AbstractSyntaxTree {
|
|
|
252
251
|
output.push(op);
|
|
253
252
|
}
|
|
254
253
|
if (!foundLeftParen) {
|
|
255
|
-
throw new Error(
|
|
254
|
+
throw new Error(`[SQLBuilder.AST] Mismatched parentheses: Found closing ')' without a matching '('. Check your IF condition syntax.`);
|
|
255
|
+
;
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
break;
|
|
@@ -262,7 +262,7 @@ class AbstractSyntaxTree {
|
|
|
262
262
|
while (operatorStack.length) {
|
|
263
263
|
const op = operatorStack.pop();
|
|
264
264
|
if (op.value === '(' || op.value === ')') {
|
|
265
|
-
throw new Error(
|
|
265
|
+
throw new Error(`[SQLBuilder.AST] Mismatched parentheses: An extra '${op.value}' was found or a matching '(' is missing.`);
|
|
266
266
|
}
|
|
267
267
|
output.push(op);
|
|
268
268
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract-syntax-tree.js","sourceRoot":"","sources":["../src/abstract-syntax-tree.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAmC;AAYnC,8BAA8B;AAC9B,MAAM,UAAU,GAKZ;IACF,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE;IAC9C,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE;IAC9C,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE;IAC9C,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE;IAC9C,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE;IAC/C,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE;IAC/C,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE;IAC7C,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE;IAC9C,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE;IAC7C,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE;IAC9C,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,aAAa;CAC7D,CAAC;AAEF;;;GAGG;AACH,MAAa,kBAAkB;IAE7B;;;;;;OAMG;IACI,iBAAiB,CAAC,SAAiB,EAAE,MAA2B;QACrE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACxC,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YACnD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,
|
|
1
|
+
{"version":3,"file":"abstract-syntax-tree.js","sourceRoot":"","sources":["../src/abstract-syntax-tree.ts"],"names":[],"mappings":"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"}
|
package/lib/common.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
type PropertyResult = {
|
|
2
|
+
exists: boolean;
|
|
3
|
+
value: any;
|
|
4
|
+
};
|
|
1
5
|
/**
|
|
2
6
|
* entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値を取得する
|
|
3
7
|
*
|
|
@@ -6,3 +10,20 @@
|
|
|
6
10
|
* @returns {any}
|
|
7
11
|
*/
|
|
8
12
|
export declare function getProperty(entity: Record<string, any>, property: string): any;
|
|
13
|
+
/**
|
|
14
|
+
* entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値が存在するかチェックする
|
|
15
|
+
*
|
|
16
|
+
* @param {Record<string, any>} entity
|
|
17
|
+
* @param {string} property
|
|
18
|
+
* @returns {boolean}
|
|
19
|
+
*/
|
|
20
|
+
export declare function hasProperty(entity: Record<string, any>, property: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値を取得する
|
|
23
|
+
*
|
|
24
|
+
* @param {Record<string, any>} entity
|
|
25
|
+
* @param {string} property
|
|
26
|
+
* @returns {PropertyResult}
|
|
27
|
+
*/
|
|
28
|
+
export declare function getPropertyResult(entity: Record<string, any>, property: string): PropertyResult;
|
|
29
|
+
export {};
|
package/lib/common.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getProperty = getProperty;
|
|
4
|
+
exports.hasProperty = hasProperty;
|
|
5
|
+
exports.getPropertyResult = getPropertyResult;
|
|
4
6
|
/**
|
|
5
7
|
* entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値を取得する
|
|
6
8
|
*
|
|
@@ -9,16 +11,42 @@ exports.getProperty = getProperty;
|
|
|
9
11
|
* @returns {any}
|
|
10
12
|
*/
|
|
11
13
|
function getProperty(entity, property) {
|
|
14
|
+
return getPropertyResult(entity, property).value;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値が存在するかチェックする
|
|
18
|
+
*
|
|
19
|
+
* @param {Record<string, any>} entity
|
|
20
|
+
* @param {string} property
|
|
21
|
+
* @returns {boolean}
|
|
22
|
+
*/
|
|
23
|
+
function hasProperty(entity, property) {
|
|
24
|
+
return getPropertyResult(entity, property).exists;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* entityで指定したオブジェクトからドットで連結されたプロパティキーに該当する値を取得する
|
|
28
|
+
*
|
|
29
|
+
* @param {Record<string, any>} entity
|
|
30
|
+
* @param {string} property
|
|
31
|
+
* @returns {PropertyResult}
|
|
32
|
+
*/
|
|
33
|
+
function getPropertyResult(entity, property) {
|
|
12
34
|
// `?.` または `.` でパスを分割
|
|
13
35
|
const propertyPath = property.split(/(\?\.)|\./).filter(Boolean);
|
|
14
36
|
// 再帰呼び出し用のヘルパー関数
|
|
15
37
|
const get = (obj, keys) => {
|
|
16
38
|
if (keys.length === 0) {
|
|
17
|
-
return
|
|
39
|
+
return {
|
|
40
|
+
exists: true,
|
|
41
|
+
value: obj
|
|
42
|
+
};
|
|
18
43
|
}
|
|
19
44
|
// オプショナルチェイニングのチェック
|
|
20
45
|
if (obj == null) {
|
|
21
|
-
return
|
|
46
|
+
return {
|
|
47
|
+
exists: false,
|
|
48
|
+
value: undefined
|
|
49
|
+
};
|
|
22
50
|
}
|
|
23
51
|
const currentKey = keys[0];
|
|
24
52
|
const remainingKeys = keys.slice(1);
|
|
@@ -27,8 +55,11 @@ function getProperty(entity, property) {
|
|
|
27
55
|
return get(obj, remainingKeys);
|
|
28
56
|
}
|
|
29
57
|
// プロパティが存在しない場合は undefined を返す
|
|
30
|
-
if (!
|
|
31
|
-
return
|
|
58
|
+
if (!Object.prototype.hasOwnProperty.call(obj, currentKey)) {
|
|
59
|
+
return {
|
|
60
|
+
exists: false,
|
|
61
|
+
value: undefined
|
|
62
|
+
};
|
|
32
63
|
}
|
|
33
64
|
return get(obj[currentKey], remainingKeys);
|
|
34
65
|
};
|
package/lib/common.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":";;AAYA,kCAEC;AASD,kCAEC;AASD,8CAqCC;AAlED;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,MAA2B,EAAE,QAAgB;IACvE,OAAO,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC;AACnD,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,MAA2B,EAAE,QAAgB;IACvE,OAAO,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,MAA2B,EAAE,QAAgB;IAC7E,sBAAsB;IACtB,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjE,iBAAiB;IACjB,MAAM,GAAG,GAAG,CAAC,GAAwB,EAAE,IAAc,EAAO,EAAE;QAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,GAAG;aACO,CAAC;QACtB,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChB,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,KAAK,EAAE,SAAS;aACC,CAAC;QACtB,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAEpC,kBAAkB;QAClB,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACjC,CAAC;QACD,+BAA+B;QAC/B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC;YAC3D,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,KAAK,EAAE,SAAS;aACC,CAAC;QACtB,CAAC;QACD,OAAO,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,CAAC;IAC7C,CAAC,CAAC;IACF,OAAO,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AACnC,CAAC"}
|
package/lib/sql-builder.d.ts
CHANGED
|
@@ -90,7 +90,7 @@ export declare class SQLBuilder {
|
|
|
90
90
|
* @param {SharedIndex} pos 現在処理している文字列の先頭インデックス
|
|
91
91
|
* @param {string} template
|
|
92
92
|
* @param {Record<string, any>} entity
|
|
93
|
-
* @param {TagContext[]} tagContexts
|
|
93
|
+
* @param {(TagContext | ParentTagContext)[]} tagContexts
|
|
94
94
|
* @param {*} [options]
|
|
95
95
|
* ├ bindType BindType
|
|
96
96
|
* ├ bindIndex number
|
|
@@ -98,6 +98,26 @@ export declare class SQLBuilder {
|
|
|
98
98
|
* @returns {string}
|
|
99
99
|
*/
|
|
100
100
|
private parse;
|
|
101
|
+
/**
|
|
102
|
+
* 指定したタグから親を遡り、指定したタグタイプのタグコンテキストを返す
|
|
103
|
+
* 見つからない場合はundefinedを返す
|
|
104
|
+
*
|
|
105
|
+
* @param {TagContext | ParentTagContext | null} tagContext
|
|
106
|
+
* @param {T} tagType
|
|
107
|
+
* @returns {(TagContext & { type: T }) | undefined}
|
|
108
|
+
*/
|
|
109
|
+
private findParentTagContext;
|
|
110
|
+
/**
|
|
111
|
+
* 指定したタグの兄弟をたどり、指定したタグタイプのタグコンテキストを返す
|
|
112
|
+
* 見つからない場合はundefinedを返す
|
|
113
|
+
* ユースケースとしては、ELSEIF/ELSEから同じIFに属するENDを探す
|
|
114
|
+
*
|
|
115
|
+
* @param {TagContext} tagContext
|
|
116
|
+
* @param {TagType | TagType[]} tagType
|
|
117
|
+
* @param {'previous' | 'next'} direction
|
|
118
|
+
* @returns {TagContext | undefined}
|
|
119
|
+
*/
|
|
120
|
+
private seekSiblingTagContext;
|
|
101
121
|
/**
|
|
102
122
|
* ダミーパラメータの終了インデックスを返す
|
|
103
123
|
*
|