@devbro/neko-sql 0.1.16 → 0.1.17

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/dist/index.js CHANGED
@@ -76,7 +76,8 @@ var Query = class _Query {
76
76
  having: [],
77
77
  orderBy: [],
78
78
  limit: null,
79
- offset: null
79
+ offset: null,
80
+ alias: null
80
81
  };
81
82
  table(tableName) {
82
83
  this.parts.table = tableName;
@@ -166,7 +167,15 @@ var Query = class _Query {
166
167
  return this.grammar.toSql(this);
167
168
  }
168
169
  async get() {
169
- return await this.connection?.runQuery(this.toSql());
170
+ let sql = this.toSql();
171
+ return await this.connection?.runQuery(sql);
172
+ }
173
+ async first() {
174
+ let rc = await this.connection?.runQuery(this.toSql());
175
+ if (rc && Array.isArray(rc) && rc.length > 0) {
176
+ return rc[0];
177
+ }
178
+ return void 0;
170
179
  }
171
180
  async count() {
172
181
  const csql = this.grammar.compileCount(this);
@@ -232,9 +241,14 @@ var Query = class _Query {
232
241
  crossJoin(table, conditions) {
233
242
  return this.join(table, "cross", conditions);
234
243
  }
244
+ alias(alias) {
245
+ this.parts.alias = alias;
246
+ return this;
247
+ }
235
248
  };
236
249
 
237
250
  // src/QueryGrammar.mts
251
+ var import_sql_tokenizer = require("sql-tokenizer");
238
252
  function toUpperFirst(str) {
239
253
  return str.substring(0, 1).toUpperCase() + str.substring(1);
240
254
  }
@@ -255,79 +269,118 @@ var QueryGrammar = class {
255
269
  "offset"
256
270
  ];
257
271
  toSql(query) {
258
- let sql = "";
272
+ let rc = this.toSqlParts(query);
273
+ rc.sql = this.joinArray(rc.parts);
274
+ return rc;
275
+ }
276
+ toSqlParts(query) {
277
+ let parts = [];
259
278
  let bindings = [];
260
279
  for (const part of this.sqlParts) {
261
280
  const funcName = "compile" + toUpperFirst(part);
262
281
  const r = this[funcName](query.parts[part]);
263
- if (!sql) {
264
- sql = r.sql;
265
- } else if (r.sql) {
266
- sql += " " + r.sql;
267
- }
268
282
  bindings = [...bindings, ...r.bindings];
283
+ parts = [...parts, ...r.parts];
269
284
  }
270
- return { sql, bindings };
285
+ return {
286
+ sql: "",
287
+ bindings,
288
+ parts
289
+ };
271
290
  }
272
291
  compileCount(query) {
273
292
  let sql = "";
274
293
  let bindings = [];
294
+ let parts = [];
275
295
  for (const part of this.sqlParts) {
276
- let parts = query.parts[part];
296
+ let parts2 = query.parts[part];
277
297
  if (part === "select") {
278
- parts = ["count(*) as count"];
298
+ parts2 = ["count(*) as count"];
279
299
  }
280
300
  const funcName = "compile" + toUpperFirst(part);
281
- const r = this[funcName](parts);
282
- if (!sql) {
283
- sql = r.sql;
284
- } else if (r.sql) {
285
- sql += " " + r.sql;
286
- }
301
+ const r = this[funcName](parts2);
287
302
  bindings = [...bindings, ...r.bindings];
303
+ parts = [...parts, ...r.parts];
288
304
  }
289
- return { sql, bindings };
305
+ return { sql, parts, bindings };
290
306
  }
291
307
  compileSelect(selects) {
292
- const rc = selects.map((v) => {
293
- return v;
294
- }).join(", ");
295
- return { sql: "select " + rc, bindings: [] };
308
+ const parts = ["select"];
309
+ selects.map((v) => {
310
+ parts.push(v);
311
+ parts.push(",");
312
+ });
313
+ parts.pop();
314
+ return { sql: this.joinArray(parts), parts, bindings: [] };
296
315
  }
297
- compileTable(tableName) {
316
+ joinArray(arr) {
298
317
  let rc = "";
318
+ let last = "";
319
+ for (const a of arr) {
320
+ if (a === ",") {
321
+ rc += a;
322
+ } else if (last === "(" || last === " " || a === ")") {
323
+ rc += a;
324
+ } else if (a === "") {
325
+ rc += "";
326
+ } else {
327
+ rc += " " + a;
328
+ }
329
+ last = a;
330
+ }
331
+ return rc.trim();
332
+ }
333
+ compileTable(tableName) {
334
+ let parts = [];
299
335
  if (tableName.length) {
300
- rc = "from " + tableName;
336
+ parts.push("from");
337
+ parts.push(tableName);
301
338
  }
302
- return { sql: rc, bindings: [] };
339
+ return { sql: parts.join(" "), parts, bindings: [] };
303
340
  }
304
341
  compileJoin(joins) {
305
342
  let sql = "";
306
343
  let bindings = [];
344
+ let parts = [];
307
345
  for (const j of joins) {
308
- sql += " " + j.type + " join " + j.table + " on ";
309
- const where = this.compileWhere(j.conditions);
310
- if (where.sql.startsWith("where ")) {
311
- where.sql = where.sql.substring("where ".length);
346
+ let table = "";
347
+ let table_bindings = [];
348
+ parts.push(j.type);
349
+ parts.push("join");
350
+ if (typeof j.table === "string") {
351
+ parts.push(j.table);
352
+ } else {
353
+ const subQuery = j.table;
354
+ const { parts: parts2, bindings: bindings2 } = subQuery.toSql();
355
+ parts = [...parts, "(", ...parts2, ")", "as", subQuery.parts.alias || "subquery"];
356
+ table_bindings = bindings2;
312
357
  }
313
- sql += "(";
314
- sql += where.sql;
315
- sql += ")";
316
- bindings = [...bindings, ...where.bindings];
358
+ parts.push("on");
359
+ const where = this.compileWhere(j.conditions);
360
+ const where_parts = where.parts;
361
+ where_parts.shift();
362
+ parts.push("(");
363
+ parts = [...parts, ...where_parts];
364
+ parts.push(")");
365
+ bindings = [...bindings, ...table_bindings, ...where.bindings];
317
366
  }
318
- return { sql, bindings };
367
+ return { sql, parts, bindings };
319
368
  }
320
369
  compileWhere(wheres) {
321
370
  let sql = "";
322
371
  let bindings = [];
372
+ let parts = [];
323
373
  for (const w of wheres) {
324
374
  sql += " " + w.joinCondition + " ";
375
+ parts.push(w.joinCondition);
325
376
  if (w.negateCondition) {
326
377
  sql += "not ";
378
+ parts.push("not");
327
379
  }
328
380
  const funcName = "compileWhere" + toUpperFirst(w.type);
329
381
  const wh = this[funcName](w);
330
382
  sql += wh.sql;
383
+ parts = parts.concat(wh.parts);
331
384
  bindings = [...bindings, ...wh.bindings];
332
385
  }
333
386
  if (sql.startsWith(" and ")) {
@@ -335,160 +388,197 @@ var QueryGrammar = class {
335
388
  } else if (sql.startsWith(" or ")) {
336
389
  sql = "where " + sql.substring(" or ".length);
337
390
  }
338
- return { sql, bindings };
391
+ if (parts.length > 0) {
392
+ parts[0] = "where";
393
+ }
394
+ return { sql, parts, bindings };
339
395
  }
340
396
  compileWhereNested(w) {
341
397
  const subQuery = w.query;
342
- const { sql, bindings } = subQuery.grammar.compileWhere(subQuery.parts.where);
398
+ let parts = [];
399
+ const { sql, parts: parts2, bindings } = subQuery.grammar.compileWhere(subQuery.parts.where);
343
400
  let sql2 = sql.replace(/^where /, "");
401
+ parts2.shift();
402
+ parts.push("(");
403
+ parts = parts.concat(parts2);
404
+ parts.push(")");
344
405
  return {
345
406
  sql: `(${sql2})`,
407
+ parts,
346
408
  bindings
347
409
  };
348
410
  }
349
411
  compileWhereOperation(w) {
350
412
  if (w.operation.toLowerCase() === "in" && Array.isArray(w.value)) {
351
413
  return {
352
- sql: `${w.column} = ANY(${this.getVariablePlaceholder()})`,
414
+ sql: `${w.column} = ANY( ? )`,
415
+ parts: [w.column, " = ANY(", "?", ")"],
353
416
  bindings: [w.value]
354
417
  };
355
418
  }
356
419
  return {
357
- sql: `${w.column} ${w.operation} ${this.getVariablePlaceholder()}`,
420
+ sql: `${w.column} ${w.operation} ?`,
421
+ parts: [w.column, w.operation, "?"],
358
422
  bindings: [w.value]
359
423
  };
360
424
  }
361
425
  compileWhereOperationColumn(w) {
362
426
  return {
363
427
  sql: `${w.column1} ${w.operation} ${w.column2}`,
428
+ parts: [w.column1, w.operation, w.column2],
364
429
  bindings: []
365
430
  };
366
431
  }
367
432
  compileWhereRaw(w) {
368
- let sql = w.sql.replace(/\?/g, () => this.getVariablePlaceholder());
433
+ const tokenize = (0, import_sql_tokenizer.sqlTokenizer)();
369
434
  return {
370
- sql,
435
+ sql: w.sql,
436
+ parts: tokenize(w.sql).filter((t) => t !== " "),
371
437
  bindings: w.bindings
372
438
  };
373
439
  }
374
440
  compileOrderBy(orderBy) {
375
441
  let rc = "";
442
+ let parts = [];
376
443
  if (orderBy.length) {
377
444
  rc = "order by " + orderBy.join(", ");
445
+ parts.push("order by");
446
+ parts = parts.concat(orderBy);
378
447
  }
379
- return { sql: rc, bindings: [] };
448
+ return { sql: rc, parts, bindings: [] };
380
449
  }
381
450
  compileLimit(limit) {
382
451
  let rc = "";
452
+ let parts = [];
383
453
  if (limit !== null) {
384
454
  rc = "limit " + limit;
455
+ parts.push("limit");
456
+ parts.push(limit);
385
457
  }
386
- return { sql: rc, bindings: [] };
458
+ return { sql: rc, parts, bindings: [] };
387
459
  }
388
460
  compileOffset(offset) {
389
461
  let rc = "";
462
+ let parts = [];
390
463
  if (offset !== null) {
391
464
  rc = "offset " + offset;
465
+ parts.push("offset");
466
+ parts.push(offset);
392
467
  }
393
- return { sql: rc, bindings: [] };
468
+ return { sql: rc, parts, bindings: [] };
394
469
  }
395
470
  compileWhereNull(w) {
396
471
  return {
397
472
  sql: `${w.column} is null`,
473
+ parts: [w.column, "is", "null"],
398
474
  bindings: []
399
475
  };
400
476
  }
401
477
  compileInsert(query, data) {
402
- let sql = "insert into " + query.parts.table + " (";
478
+ let parts = ["insert", "into", query.parts.table, "("];
403
479
  const columns = [];
404
480
  const bindings = [];
405
481
  const values = [];
406
482
  for (const [k, v] of Object.entries(data)) {
407
- columns.push(k);
483
+ parts.push(k);
484
+ parts.push(",");
485
+ }
486
+ parts.pop();
487
+ parts = parts.concat([")", "values", "("]);
488
+ for (const [k, v] of Object.entries(data)) {
489
+ parts.push("?");
408
490
  bindings.push(v);
409
- values.push(this.getVariablePlaceholder());
491
+ parts.push(",");
410
492
  }
411
- sql += columns.join(", ") + ") values (" + values + ")";
412
- return { sql, bindings };
493
+ parts.pop();
494
+ parts.push(")");
495
+ return { sql: parts.join(" "), parts, bindings };
413
496
  }
414
497
  compileUpdate(query, data) {
415
- let sql = "update " + query.parts.table + " set ";
416
498
  const bindings = [];
499
+ let parts = ["update", query.parts.table, "set"];
417
500
  const setParts = [];
418
501
  for (const [k, v] of Object.entries(data)) {
419
- setParts.push(`${k} = ${this.getVariablePlaceholder()}`);
502
+ parts = parts.concat([k, "=", "?", ","]);
503
+ setParts.push(`${k} = ?`);
420
504
  bindings.push(v);
421
505
  }
422
- sql += setParts.join(", ");
506
+ parts.pop();
423
507
  const where_csql = this.compileWhere(query.parts.where);
424
- sql += " " + where_csql.sql;
508
+ parts = parts.concat(where_csql.parts);
425
509
  bindings.push(...where_csql.bindings);
426
- return { sql, bindings };
510
+ return { sql: parts.join(" "), parts, bindings };
427
511
  }
428
512
  compileDelete(query) {
429
513
  let sql = "delete from " + query.parts.table;
514
+ let parts = ["delete", "from", query.parts.table];
430
515
  const where_csql = this.compileWhere(query.parts.where);
431
516
  sql += " " + where_csql.sql;
432
- return { sql, bindings: where_csql.bindings };
517
+ parts = parts.concat(where_csql.parts);
518
+ return { sql, parts, bindings: where_csql.bindings };
433
519
  }
434
520
  compileUpsert(query, data, conflictFields, updateFields) {
435
- let sql = "insert into " + query.parts.table + " (";
436
- const columns = [];
521
+ let parts = [];
437
522
  const bindings = [];
438
- const values = [];
439
- for (const [k, v] of Object.entries(data)) {
440
- columns.push(k);
441
- bindings.push(v);
442
- values.push(this.getVariablePlaceholder());
443
- }
444
- sql += columns.join(", ") + ") values (" + values + ")";
445
- sql += " on conflict (" + conflictFields.join(", ") + ") do update set ";
523
+ let isql = this.compileInsert(query, data);
524
+ parts = isql.parts;
525
+ bindings.push(...isql.bindings);
526
+ parts = parts.concat(["on", "conflict", "(", ...conflictFields, ")", "do", "update", "set"]);
446
527
  const setParts = [];
447
528
  for (const f of updateFields) {
448
529
  setParts.push(`${f} = excluded.${f}`);
530
+ setParts.push(`,`);
449
531
  }
450
- sql += setParts.join(", ");
532
+ setParts.pop();
533
+ parts = parts.concat(setParts);
451
534
  const where_csql = this.compileWhere(query.parts.where);
452
- sql += " " + where_csql.sql;
535
+ parts = parts.concat(where_csql.parts);
453
536
  bindings.push(...where_csql.bindings);
454
- return { sql, bindings };
537
+ return { sql: parts.join(" "), parts, bindings };
455
538
  }
456
539
  compileGroupBy(groupBy) {
457
540
  let rc = "";
541
+ let parts = [];
458
542
  if (groupBy.length) {
459
543
  rc = "group by " + groupBy.join(", ");
544
+ parts.push("group by");
545
+ parts = parts.concat(groupBy);
460
546
  }
461
- return { sql: rc, bindings: [] };
547
+ return { sql: rc, parts, bindings: [] };
462
548
  }
463
549
  compileHaving(having) {
464
550
  let sql = "";
465
551
  let bindings = [];
552
+ let parts = [];
466
553
  for (const w of having) {
467
554
  sql += " " + w.joinCondition + " ";
555
+ parts.push(w.joinCondition);
468
556
  if (w.negateCondition) {
469
557
  sql += "not ";
558
+ parts.push("not");
470
559
  }
471
560
  const funcName = "compileHaving" + toUpperFirst(w.type);
472
561
  const wh = this[funcName](w);
562
+ parts = parts.concat(wh.parts);
473
563
  sql += wh.sql;
474
564
  bindings = [...bindings, ...wh.bindings];
475
565
  }
476
- if (sql.startsWith(" and ")) {
477
- sql = "having " + sql.substring(" and ".length);
478
- } else if (sql.startsWith(" or ")) {
479
- sql = "having " + sql.substring(" or ".length);
566
+ if (parts.length > 0) {
567
+ parts[0] = "having";
480
568
  }
481
- return { sql, bindings };
569
+ return { sql: parts.join(" "), parts, bindings };
482
570
  }
483
571
  compileHavingOperation(w) {
484
572
  return {
485
- sql: `${w.column} ${w.operation} ${this.getVariablePlaceholder()}`,
573
+ sql: `${w.column} ${w.operation} ?`,
574
+ parts: [w.column, w.operation, "?"],
486
575
  bindings: [w.value]
487
576
  };
488
577
  }
489
578
  compileHavingRaw(w) {
490
579
  return {
491
580
  sql: w.sql,
581
+ parts: w.sql.split(" "),
492
582
  bindings: w.bindings
493
583
  };
494
584
  }
@@ -499,47 +589,36 @@ var PostgresqlQueryGrammar = class extends QueryGrammar {
499
589
  static {
500
590
  __name(this, "PostgresqlQueryGrammar");
501
591
  }
502
- parameterIndex;
503
592
  constructor() {
504
593
  super();
505
- this.parameterIndex = 1;
506
594
  }
507
595
  toSql(query) {
508
- this.parameterIndex = 1;
509
596
  return super.toSql(query);
510
597
  }
511
- getVariablePlaceholder() {
512
- return "$" + this.parameterIndex++;
513
- }
514
598
  compileInsert(query, data) {
515
- this.parameterIndex = 1;
516
599
  return super.compileInsert(query, data);
517
600
  }
518
601
  compileInsertGetId(query, data, options = { primaryKey: ["id"] }) {
519
- this.parameterIndex = 1;
520
602
  const rc = super.compileInsert(query, data);
521
603
  rc.sql += ` RETURNING ${options.primaryKey.join(", ")}`;
522
604
  return rc;
523
605
  }
524
606
  compileUpdate(query, data) {
525
- this.parameterIndex = 1;
526
607
  return super.compileUpdate(query, data);
527
608
  }
528
609
  compileDelete(query) {
529
- this.parameterIndex = 1;
530
610
  return super.compileDelete(query);
531
611
  }
532
612
  compileUpsert(query, data, conflictFields, updateFields) {
533
- this.parameterIndex = 1;
534
613
  return super.compileUpsert(query, data, conflictFields, updateFields);
535
614
  }
536
615
  compileCount(query) {
537
- this.parameterIndex = 1;
538
616
  return super.compileCount(query);
539
617
  }
540
618
  };
541
619
 
542
620
  // src/Expression.mts
621
+ var import_sql_tokenizer2 = require("sql-tokenizer");
543
622
  var Expression = class {
544
623
  constructor(sql = "", bindings = []) {
545
624
  this.sql = sql;
@@ -549,7 +628,8 @@ var Expression = class {
549
628
  __name(this, "Expression");
550
629
  }
551
630
  toCompiledSql() {
552
- return { sql: this.sql, bindings: this.bindings };
631
+ const tokenize = (0, import_sql_tokenizer2.sqlTokenizer)(this.sql);
632
+ return { sql: this.sql, bindings: this.bindings, parts: tokenize(this.sql) };
553
633
  }
554
634
  };
555
635
 
@@ -793,13 +873,14 @@ var SchemaGrammar = class {
793
873
  });
794
874
  }
795
875
  sql += [columns, primaryKeys, ...foreignKeys].join(",") + ")";
796
- const compiledSql = { sql, bindings: [] };
876
+ const compiledSql = { sql, parts: [], bindings: [] };
797
877
  if (blueprint.indexes.length > 0) {
798
878
  const indexSqls = blueprint.indexes.map((index) => {
799
879
  return this.compileIndex(blueprint.tableName, index);
800
880
  });
801
881
  return {
802
882
  sql: [compiledSql.sql, ...indexSqls.map((idx) => idx.sql)].join("; "),
883
+ parts: [],
803
884
  bindings: compiledSql.bindings
804
885
  };
805
886
  }
@@ -819,9 +900,9 @@ var SchemaGrammar = class {
819
900
  }
820
901
  let compiledSql;
821
902
  if (alterStatements.length > 0) {
822
- compiledSql = { sql: sql.join(" "), bindings: [] };
903
+ compiledSql = { sql: sql.join(" "), parts: [], bindings: [] };
823
904
  } else {
824
- compiledSql = { sql: sql.join(" ") + " ", bindings: [] };
905
+ compiledSql = { sql: sql.join(" ") + " ", parts: [], bindings: [] };
825
906
  }
826
907
  if (blueprint.indexes.length > 0) {
827
908
  const indexSqls = blueprint.indexes.map((index) => {
@@ -829,6 +910,7 @@ var SchemaGrammar = class {
829
910
  });
830
911
  return {
831
912
  sql: [compiledSql.sql, ...indexSqls.map((idx) => idx.sql)].join("; "),
913
+ parts: [],
832
914
  bindings: compiledSql.bindings
833
915
  };
834
916
  }
@@ -908,20 +990,26 @@ var SchemaGrammar = class {
908
990
  compileTables(schema = void 0) {
909
991
  return {
910
992
  sql: "select c.relname as name, n.nspname as schema, pg_total_relation_size(c.oid) as size, obj_description(c.oid, 'pg_class') as comment from pg_class c, pg_namespace n where c.relkind in ('r', 'p') and n.oid = c.relnamespace and " + this.compileSchemaWhereClause(schema, "n.nspname") + " order by n.nspname, c.relname",
993
+ parts: [],
911
994
  bindings: []
912
995
  };
913
996
  }
914
997
  compileTableExists(tableName, schema = "") {
915
998
  return {
916
999
  sql: "select exists (select 1 from pg_class c, pg_namespace n where n.nspname = " + (schema ? this.escape(schema) : "current_schema()") + " and c.relname = $1 and c.relkind in ('r', 'p') and n.oid = c.relnamespace)",
1000
+ parts: [],
917
1001
  bindings: [tableName]
918
1002
  };
919
1003
  }
920
1004
  compileDropTable(tableName) {
921
- return { sql: `drop table ${this.doubleQuoteString(tableName)}`, bindings: [] };
1005
+ return { sql: `drop table ${this.doubleQuoteString(tableName)}`, parts: [], bindings: [] };
922
1006
  }
923
1007
  compileDropTableIfExists(tableName) {
924
- return { sql: `drop table if exists ${this.doubleQuoteString(tableName)}`, bindings: [] };
1008
+ return {
1009
+ sql: `drop table if exists ${this.doubleQuoteString(tableName)}`,
1010
+ parts: [],
1011
+ bindings: []
1012
+ };
925
1013
  }
926
1014
  compileSchemaWhereClause(schema, column) {
927
1015
  if (Array.isArray(schema) && schema.length > 0) {
@@ -960,7 +1048,7 @@ var SchemaGrammar = class {
960
1048
  const uniqueKeyword = index.unique ? "unique " : "";
961
1049
  const indexType = index._type ? ` using ${index._type}` : "";
962
1050
  const sql = `create ${uniqueKeyword}index ${indexName} on ${tableName}${indexType} (${index.columns.join(", ")})`;
963
- return { sql, bindings: [] };
1051
+ return { sql, parts: [], bindings: [] };
964
1052
  }
965
1053
  };
966
1054
 
@@ -979,7 +1067,7 @@ var Schema = class {
979
1067
  structMethod(blueprint);
980
1068
  const grammar = new SchemaGrammar();
981
1069
  const sql = grammar.toSql(blueprint);
982
- await this.connection?.runQuery({ sql, bindings: [] });
1070
+ await this.connection?.runQuery({ sql, parts: [], bindings: [] });
983
1071
  }
984
1072
  async alterTable(tableName, structMethod) {
985
1073
  const blueprint = new Blueprint();
@@ -987,7 +1075,7 @@ var Schema = class {
987
1075
  structMethod(blueprint);
988
1076
  const grammar = new SchemaGrammar();
989
1077
  const sql = grammar.toSql(blueprint);
990
- await this.connection?.runQuery({ sql, bindings: [] });
1078
+ await this.connection?.runQuery({ sql, parts: [], bindings: [] });
991
1079
  }
992
1080
  async dropTable(tableName) {
993
1081
  const grammar = new SchemaGrammar();
@@ -1043,7 +1131,12 @@ var PostgresqlConnection = class _PostgresqlConnection extends Connection {
1043
1131
  return true;
1044
1132
  }
1045
1133
  async runQuery(sql) {
1046
- const result = await this.connection?.query(sql.sql, sql.bindings);
1134
+ let counter = 1;
1135
+ let sql2 = sql.sql;
1136
+ if (sql.parts && sql.parts.length > 0) {
1137
+ sql2 = sql.parts.map((v) => v === "?" ? "$" + counter++ : v).join(" ");
1138
+ }
1139
+ const result = await this.connection?.query(sql2, sql.bindings);
1047
1140
  return result?.rows;
1048
1141
  }
1049
1142
  async runCursor(sql) {