sqlstack 1.0.18 → 1.0.19

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.
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/adapters/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA2B5C,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2IlF"}
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/adapters/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA8F5C,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyJlF"}
@@ -34,6 +34,75 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.createSqliteDb = createSqliteDb;
37
+ function isPromiseLike(value) {
38
+ return !!value && typeof value.then === 'function';
39
+ }
40
+ async function prepareStatement(db, sql) {
41
+ const stmt = db.prepare(sql);
42
+ return isPromiseLike(stmt) ? await stmt : stmt;
43
+ }
44
+ async function finalizeStatement(stmt) {
45
+ if (!stmt || typeof stmt.finalize !== 'function')
46
+ return;
47
+ const result = stmt.finalize();
48
+ if (isPromiseLike(result)) {
49
+ await result;
50
+ }
51
+ }
52
+ async function statementAll(stmt, params) {
53
+ if (typeof stmt.all !== 'function') {
54
+ throw new Error('SQLite statement missing all()');
55
+ }
56
+ if (stmt.all.length >= 2) {
57
+ return await new Promise((resolve, reject) => {
58
+ const callback = (err, rows) => {
59
+ if (err)
60
+ return reject(err);
61
+ resolve(rows || []);
62
+ };
63
+ try {
64
+ if (params.length > 0) {
65
+ stmt.all(params, callback);
66
+ }
67
+ else {
68
+ stmt.all(callback);
69
+ }
70
+ }
71
+ catch (error) {
72
+ reject(error);
73
+ }
74
+ });
75
+ }
76
+ const result = stmt.all(...params);
77
+ return isPromiseLike(result) ? await result : result;
78
+ }
79
+ async function statementRun(stmt, params) {
80
+ if (typeof stmt.run !== 'function') {
81
+ throw new Error('SQLite statement missing run()');
82
+ }
83
+ if (stmt.run.length >= 2) {
84
+ return await new Promise((resolve, reject) => {
85
+ const callback = function (err) {
86
+ if (err)
87
+ return reject(err);
88
+ resolve({ changes: this?.changes ?? 0, lastInsertId: this?.lastID });
89
+ };
90
+ try {
91
+ if (params.length > 0) {
92
+ stmt.run(params, callback);
93
+ }
94
+ else {
95
+ stmt.run(callback);
96
+ }
97
+ }
98
+ catch (error) {
99
+ reject(error);
100
+ }
101
+ });
102
+ }
103
+ const result = stmt.run(...params);
104
+ return isPromiseLike(result) ? await result : result;
105
+ }
37
106
  function stripLeadingComments(sql) {
38
107
  let i = 0;
39
108
  const n = sql.length;
@@ -71,17 +140,32 @@ async function createSqliteDb(filenameOrDb) {
71
140
  return {
72
141
  dialect: 'sqlite',
73
142
  async query(sql, params) {
74
- const stmt = db.prepare(sql);
75
- const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();
76
- if (text.startsWith('SELECT') || text.startsWith('WITH')) {
77
- return stmt.all(...params);
143
+ const stmt = await prepareStatement(db, sql);
144
+ try {
145
+ const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();
146
+ if (text.startsWith('SELECT') || text.startsWith('WITH')) {
147
+ const rows = await statementAll(stmt, params);
148
+ return rows;
149
+ }
150
+ const info = await statementRun(stmt, params);
151
+ const rowsAffected = Number(info?.changes ?? info?.rowsAffected ?? 0);
152
+ const lastInsertId = info?.lastInsertRowid ?? info?.lastID ?? info?.lastInsertId;
153
+ return { rowsAffected, lastInsertId };
154
+ }
155
+ finally {
156
+ await finalizeStatement(stmt);
78
157
  }
79
- const info = stmt.run(...params);
80
- return { rowsAffected: Number(info?.changes ?? 0), lastInsertId: info?.lastInsertRowid };
81
158
  },
82
159
  conn: db,
83
160
  // Do not close externally provided connection
84
- close() { },
161
+ async close() {
162
+ if (typeof db.close === 'function') {
163
+ const res = db.close();
164
+ if (isPromiseLike(res)) {
165
+ await res;
166
+ }
167
+ }
168
+ },
85
169
  };
86
170
  }
87
171
  // sqlite3 shape
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/adapters/sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database } from '../registry';\n\nfunction stripLeadingComments(sql: string): string {\n let i = 0;\n const n = sql.length;\n if (sql.charCodeAt(0) === 0xfeff) i = 1; // BOM\n while (i < n) {\n while (i < n && /\\s/.test(sql[i]!)) i++;\n if (i + 1 < n && sql[i] === '-' && sql[i + 1] === '-') {\n // -- line comment\n i += 2;\n while (i < n && sql[i] !== '\\n') i++;\n continue;\n }\n if (i + 1 < n && sql[i] === '/' && sql[i + 1] === '*') {\n // /* block comment */\n i += 2;\n const end = sql.indexOf('*/', i);\n if (end === -1) return '';\n i = end + 2;\n continue;\n }\n break;\n }\n return sql.slice(i);\n}\n\nexport async function createSqliteDb(filenameOrDb: string | any): Promise<Database> {\n // If a pre-created connection is provided\n if (typeof filenameOrDb !== 'string' && filenameOrDb) {\n const db = filenameOrDb;\n\n // better-sqlite3 shape\n if (typeof db.prepare === 'function') {\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = db.prepare(sql);\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return stmt.all(...params);\n }\n const info = stmt.run(...params);\n return { rowsAffected: Number(info?.changes ?? 0), lastInsertId: info?.lastInsertRowid };\n },\n conn: db,\n // Do not close externally provided connection\n close() {},\n } as Database;\n }\n\n // sqlite3 shape\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n return new Promise((resolve, reject) => {\n // Use function callback to access `this` for metadata\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n // Do not close externally provided connection\n close() {},\n } as Database;\n }\n\n const filename = filenameOrDb as string;\n\n let BetterSqlite3: any;\n if (typeof require === 'function') {\n try {\n BetterSqlite3 = require('better-sqlite3');\n } catch {\n BetterSqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n const mod = await import('better-sqlite3');\n BetterSqlite3 = (mod as any).default ?? mod;\n } catch {\n BetterSqlite3 = null;\n }\n }\n\n if (BetterSqlite3) {\n const db = new BetterSqlite3(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = db.prepare(sql);\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return stmt.all(...params);\n }\n const info = stmt.run(...params);\n return { rowsAffected: Number(info?.changes ?? 0), lastInsertId: info?.lastInsertRowid };\n },\n conn: db,\n close() {\n db.close();\n },\n } as Database;\n }\n\n let sqlite3: any;\n if (typeof require === 'function') {\n try {\n sqlite3 = require('sqlite3');\n } catch {\n sqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n const mod = await import('sqlite3');\n sqlite3 = (mod as any).default ?? mod;\n } catch {\n sqlite3 = null;\n }\n }\n\n if (sqlite3) {\n const db = new sqlite3.Database(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n // Non-SELECT statements\n return new Promise((resolve, reject) => {\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n close() {\n return new Promise<void>((resolve, reject) => {\n db.close((err: Error | null) => (err ? reject(err) : resolve()));\n });\n },\n } as Database;\n }\n\n throw new Error('No SQLite driver available. Install either better-sqlite3 or sqlite3.');\n}\n"]}
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/adapters/sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database } from '../registry';\n\nfunction isPromiseLike<T>(value: unknown): value is Promise<T> {\n return !!value && typeof (value as Promise<T>).then === 'function';\n}\n\nasync function prepareStatement(db: any, sql: string) {\n const stmt = db.prepare(sql);\n return isPromiseLike(stmt) ? await stmt : stmt;\n}\n\nasync function finalizeStatement(stmt: any) {\n if (!stmt || typeof stmt.finalize !== 'function') return;\n const result = stmt.finalize();\n if (isPromiseLike(result)) {\n await result;\n }\n}\n\nasync function statementAll(stmt: any, params: unknown[]) {\n if (typeof stmt.all !== 'function') {\n throw new Error('SQLite statement missing all()');\n }\n if (stmt.all.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n };\n try {\n if (params.length > 0) {\n stmt.all(params, callback);\n } else {\n stmt.all(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.all(...(params as any[]));\n return isPromiseLike(result) ? await result : result;\n}\n\nasync function statementRun(stmt: any, params: unknown[]) {\n if (typeof stmt.run !== 'function') {\n throw new Error('SQLite statement missing run()');\n }\n if (stmt.run.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ changes: this?.changes ?? 0, lastInsertId: this?.lastID });\n };\n try {\n if (params.length > 0) {\n stmt.run(params, callback);\n } else {\n stmt.run(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.run(...(params as any[]));\n return isPromiseLike(result) ? await result : result;\n}\n\nfunction stripLeadingComments(sql: string): string {\n let i = 0;\n const n = sql.length;\n if (sql.charCodeAt(0) === 0xfeff) i = 1; // BOM\n while (i < n) {\n while (i < n && /\\s/.test(sql[i]!)) i++;\n if (i + 1 < n && sql[i] === '-' && sql[i + 1] === '-') {\n // -- line comment\n i += 2;\n while (i < n && sql[i] !== '\\n') i++;\n continue;\n }\n if (i + 1 < n && sql[i] === '/' && sql[i + 1] === '*') {\n // /* block comment */\n i += 2;\n const end = sql.indexOf('*/', i);\n if (end === -1) return '';\n i = end + 2;\n continue;\n }\n break;\n }\n return sql.slice(i);\n}\n\nexport async function createSqliteDb(filenameOrDb: string | any): Promise<Database> {\n // If a pre-created connection is provided\n if (typeof filenameOrDb !== 'string' && filenameOrDb) {\n const db = filenameOrDb;\n\n // better-sqlite3 shape\n if (typeof db.prepare === 'function') {\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = await prepareStatement(db, sql);\n try {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n const rows = await statementAll(stmt, params);\n return rows;\n }\n const info = await statementRun(stmt, params);\n const rowsAffected = Number(info?.changes ?? info?.rowsAffected ?? 0);\n const lastInsertId = info?.lastInsertRowid ?? info?.lastID ?? info?.lastInsertId;\n return { rowsAffected, lastInsertId };\n } finally {\n await finalizeStatement(stmt);\n }\n },\n conn: db,\n // Do not close externally provided connection\n async close() {\n if (typeof db.close === 'function') {\n const res = db.close();\n if (isPromiseLike(res)) {\n await res;\n }\n }\n },\n } as Database;\n }\n\n // sqlite3 shape\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n return new Promise((resolve, reject) => {\n // Use function callback to access `this` for metadata\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n // Do not close externally provided connection\n close() {},\n } as Database;\n }\n\n const filename = filenameOrDb as string;\n\n let BetterSqlite3: any;\n if (typeof require === 'function') {\n try {\n BetterSqlite3 = require('better-sqlite3');\n } catch {\n BetterSqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n const mod = await import('better-sqlite3');\n BetterSqlite3 = (mod as any).default ?? mod;\n } catch {\n BetterSqlite3 = null;\n }\n }\n\n if (BetterSqlite3) {\n const db = new BetterSqlite3(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = db.prepare(sql);\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return stmt.all(...params);\n }\n const info = stmt.run(...params);\n return { rowsAffected: Number(info?.changes ?? 0), lastInsertId: info?.lastInsertRowid };\n },\n conn: db,\n close() {\n db.close();\n },\n } as Database;\n }\n\n let sqlite3: any;\n if (typeof require === 'function') {\n try {\n sqlite3 = require('sqlite3');\n } catch {\n sqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n const mod = await import('sqlite3');\n sqlite3 = (mod as any).default ?? mod;\n } catch {\n sqlite3 = null;\n }\n }\n\n if (sqlite3) {\n const db = new sqlite3.Database(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n // Non-SELECT statements\n return new Promise((resolve, reject) => {\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n close() {\n return new Promise<void>((resolve, reject) => {\n db.close((err: Error | null) => (err ? reject(err) : resolve()));\n });\n },\n } as Database;\n }\n\n throw new Error('No SQLite driver available. Install either better-sqlite3 or sqlite3.');\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"sqlBinder.d.ts","sourceRoot":"","sources":["../../../src/binders/sqlBinder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,UAAU,CAAC;CAC1E;AAED,KAAK,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/C,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAq8BxD;AAED,eAAO,MAAM,iBAAiB,iBAA8B,CAAC;AAC7D,eAAO,MAAM,kBAAkB,iBAA+B,CAAC;AAC/D,eAAO,MAAM,oBAAoB,iBAAiC,CAAC;AAGnE,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"sqlBinder.d.ts","sourceRoot":"","sources":["../../../src/binders/sqlBinder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,UAAU,CAAC;CAC1E;AAED,KAAK,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/C,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAorCxD;AAED,eAAO,MAAM,iBAAiB,iBAA8B,CAAC;AAC7D,eAAO,MAAM,kBAAkB,iBAA+B,CAAC;AAC/D,eAAO,MAAM,oBAAoB,iBAAiC,CAAC;AAGnE,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -464,6 +464,211 @@ function createBinder(dialect) {
464
464
  i = insertEnd;
465
465
  continue;
466
466
  }
467
+ // Check for :batch_insert(...) syntax (case-insensitive)
468
+ const batchInsertMatch = /^:batch_insert\s*\(/i.exec(sql.slice(i));
469
+ if (batchInsertMatch) {
470
+ if (isArrayArgs) {
471
+ throw new Error(':batch_insert() syntax only works with named parameters');
472
+ }
473
+ // Parse the argument list inside parentheses
474
+ let j = i + batchInsertMatch[0].length; // Skip ':batch_insert('
475
+ const argStart = j;
476
+ let parenDepth = 1;
477
+ let inString = false;
478
+ let stringChar = '';
479
+ // Find matching closing parenthesis
480
+ while (j < len && parenDepth > 0) {
481
+ const c = sql[j];
482
+ const cNext = j + 1 < len ? sql[j + 1] : '';
483
+ if (!inString) {
484
+ if (c === "'" || c === '"') {
485
+ inString = true;
486
+ stringChar = c;
487
+ }
488
+ else if (c === '(') {
489
+ parenDepth++;
490
+ }
491
+ else if (c === ')') {
492
+ parenDepth--;
493
+ }
494
+ }
495
+ else {
496
+ if (c === stringChar) {
497
+ // Check for escaped quote
498
+ if (cNext === stringChar) {
499
+ j++; // Skip escaped quote
500
+ }
501
+ else {
502
+ inString = false;
503
+ }
504
+ }
505
+ }
506
+ if (parenDepth > 0)
507
+ j++;
508
+ }
509
+ if (parenDepth > 0) {
510
+ throw new Error('Unclosed :batch_insert() parentheses');
511
+ }
512
+ // Extract argument list (between the parentheses)
513
+ const argList = sql.slice(argStart, j).trim();
514
+ const batchInsertEnd = j + 1; // Include closing ')'
515
+ // Parse argument list (split by comma, respecting quotes and parentheses)
516
+ const items = [];
517
+ let current = '';
518
+ let inSQ = false; // single quote string
519
+ let inDQ = false; // double quote identifier
520
+ let itemParenDepth = 0;
521
+ for (let k = 0; k < argList.length; k++) {
522
+ const ch2 = argList[k];
523
+ const next2 = k + 1 < argList.length ? argList[k + 1] : '';
524
+ if (inSQ) {
525
+ current += ch2;
526
+ if (ch2 === "'" && next2 === "'") {
527
+ current += next2;
528
+ k++;
529
+ }
530
+ else if (ch2 === "'") {
531
+ inSQ = false;
532
+ }
533
+ continue;
534
+ }
535
+ if (inDQ) {
536
+ current += ch2;
537
+ if (ch2 === '"' && next2 === '"') {
538
+ current += next2;
539
+ k++;
540
+ }
541
+ else if (ch2 === '"') {
542
+ inDQ = false;
543
+ }
544
+ continue;
545
+ }
546
+ if (ch2 === "'") {
547
+ current += ch2;
548
+ inSQ = true;
549
+ continue;
550
+ }
551
+ if (ch2 === '"') {
552
+ current += ch2;
553
+ inDQ = true;
554
+ continue;
555
+ }
556
+ if (ch2 === '(') {
557
+ current += ch2;
558
+ itemParenDepth++;
559
+ continue;
560
+ }
561
+ if (ch2 === ')') {
562
+ current += ch2;
563
+ itemParenDepth--;
564
+ continue;
565
+ }
566
+ if (ch2 === ',' && itemParenDepth === 0) {
567
+ const trimmedItem = current.trim();
568
+ if (trimmedItem.length > 0) {
569
+ items.push(trimmedItem);
570
+ }
571
+ current = '';
572
+ continue;
573
+ }
574
+ current += ch2;
575
+ }
576
+ // Add the last item
577
+ const trimmedItem = current.trim();
578
+ if (trimmedItem.length > 0) {
579
+ items.push(trimmedItem);
580
+ }
581
+ if (items.length === 0) {
582
+ throw new Error(':batch_insert() requires at least one argument');
583
+ }
584
+ const obj = args;
585
+ const batchArgs = [];
586
+ const resolvePath = (root, path) => {
587
+ const segments = path.split('.').map((s) => s.trim()).filter((s) => s.length > 0);
588
+ if (segments.length === 0) {
589
+ throw new Error(`Invalid path "${path}" in :batch_insert()`);
590
+ }
591
+ const nestedArrayError = () => {
592
+ throw new Error('Nested arrays are not supported in :batch_insert()');
593
+ };
594
+ const descend = (value, idx) => {
595
+ if (idx >= segments.length) {
596
+ if (Array.isArray(value)) {
597
+ // At leaf: array-of-arrays is not allowed
598
+ for (const v of value) {
599
+ if (Array.isArray(v))
600
+ nestedArrayError();
601
+ }
602
+ return { isArray: true, values: value.slice() };
603
+ }
604
+ return { isArray: false, values: [value] };
605
+ }
606
+ const key = segments[idx];
607
+ if (Array.isArray(value)) {
608
+ // We are traversing through an array: map remaining path over each element
609
+ const rowValues = [];
610
+ for (const element of value) {
611
+ const sub = descend(element, idx);
612
+ if (sub.isArray)
613
+ nestedArrayError();
614
+ rowValues.push(sub.values[0]);
615
+ }
616
+ return { isArray: true, values: rowValues };
617
+ }
618
+ let nextVal;
619
+ if (value && typeof value === 'object' && Object.prototype.hasOwnProperty.call(value, key)) {
620
+ nextVal = value[key];
621
+ }
622
+ else {
623
+ nextVal = undefined;
624
+ }
625
+ return descend(nextVal, idx + 1);
626
+ };
627
+ return descend(root, 0);
628
+ };
629
+ for (const item of items) {
630
+ const path = item.trim();
631
+ const firstSeg = path.split('.')[0];
632
+ if (!Object.prototype.hasOwnProperty.call(obj, firstSeg)) {
633
+ throw new Error(`Path "${path}" in :batch_insert() refers to a missing key`);
634
+ }
635
+ const { isArray, values } = resolvePath(obj, path);
636
+ // Undefined is not allowed for any value
637
+ for (const v of values) {
638
+ if (v === undefined) {
639
+ throw new Error(`Path "${path}" in :batch_insert() resolved to undefined`);
640
+ }
641
+ }
642
+ batchArgs.push({ path, isArray, values });
643
+ }
644
+ const arrayArgs = batchArgs.filter((b) => b.isArray);
645
+ if (arrayArgs.length === 0) {
646
+ throw new Error(':batch_insert() requires at least one array argument');
647
+ }
648
+ const rowCount = arrayArgs[0].values.length;
649
+ if (rowCount === 0) {
650
+ throw new Error(':batch_insert() array arguments must not be empty');
651
+ }
652
+ for (const argInfo of arrayArgs) {
653
+ if (argInfo.values.length !== rowCount) {
654
+ throw new Error(':batch_insert() arrays must share the same length');
655
+ }
656
+ }
657
+ // Build VALUES clause
658
+ const valueTuples = [];
659
+ for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
660
+ const placeholders = [];
661
+ for (const argInfo of batchArgs) {
662
+ const value = argInfo.isArray ? argInfo.values[rowIndex] : argInfo.values[0];
663
+ placeholders.push(placeholder(pgIndex));
664
+ params.push(value);
665
+ }
666
+ valueTuples.push(`(${placeholders.join(', ')})`);
667
+ }
668
+ out.push('VALUES ', valueTuples.join(', '));
669
+ i = batchInsertEnd;
670
+ continue;
671
+ }
467
672
  // Check for :filter(...) syntax (case-insensitive)
468
673
  const filterMatch = /^:filter\s*\(/i.exec(sql.slice(i));
469
674
  if (filterMatch) {