@asla/yoursql 0.5.2 → 0.6.1

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 CHANGED
@@ -5,15 +5,75 @@
5
5
 
6
6
  [package]: https://img.shields.io/badge/package-ESM-ffe536.svg
7
7
  [package-url]: https://nodejs.org/api/esm.html
8
- [npm]: https://img.shields.io/npm/v/yoursql.svg
9
- [npm-url]: https://npmjs.com/package/yoursql
8
+ [npm]: https://img.shields.io/npm/v/@asla/yoursql.svg
9
+ [npm-url]: https://npmjs.com/package/@asla/yoursql
10
10
  [jsr]: https://jsr.io/badges/@asla/yoursql
11
11
  [jsr-url]: https://jsr.io/@asla/yoursql
12
- [node]: https://img.shields.io/node/v/yoursql.svg
12
+ [node]: https://img.shields.io/node/v/@asla/yoursql.svg
13
13
  [node-url]: https://nodejs.org
14
- [size]: https://packagephobia.com/badge?p=yoursql
15
- [size-url]: https://packagephobia.com/result?p=yoursql
14
+ [size]: https://packagephobia.com/badge?p=@asla%2Fyoursql
15
+ [size-url]: https://packagephobia.com/result?p=@asla%2Fyoursql
16
16
 
17
17
  SQL 生成器
18
18
 
19
19
  [API 文档](https://jsr.io/@asla/yoursql/doc)
20
+
21
+ ### 安全转将 JS 值转换为 SQL 值,避免 SQL 注入
22
+
23
+ 导入
24
+
25
+ ```ts
26
+ import { v } from "@asla/yoursql";
27
+ ```
28
+
29
+ 默认情况下,支持 PostgresSQL, 因为不同数据库的值转换有些差异,如果使用其他数据库,可能需要配置对象转换器
30
+
31
+ ```ts
32
+ v(1); // "1"
33
+ v(1n); // "1"
34
+ v("te'xt"); // "'te''xt'"
35
+ v(new Date()); // "'2024-11-30T05:08:33.112Z'"
36
+ v([1, 2, 3]); // "ARRAY[1,2,3]"
37
+ v({ id: "abc", size: 1 }); // "'{\"id\":\"abc\",\"size\":1}'"
38
+ v(null); // "NULL"
39
+ v(undefined); // "DEFAULT"
40
+ ```
41
+
42
+ 如果传入 String 对象,将保留其字符串值,不会进行任何转换
43
+
44
+ ```ts
45
+ v(new String("1+1")); // "1+1"
46
+ ```
47
+
48
+ 你可以自定义对象到字符串的转换, 例如,你想将 Set 转换为 PostgresSql 的 ARRAY[] 输入格式
49
+
50
+ ```ts
51
+ v.setTransformer(Set, function (value: Set) {
52
+ return this.v(Array.from(value));
53
+ });
54
+ ```
55
+
56
+ 转换对象数组
57
+
58
+ ```ts
59
+ const values = [{ a: 1, b: 2 }, { c: 3 }];
60
+
61
+ // 这将自动选择数组中所有键的并集
62
+ v.objectListToValuesList(values); // "(1,2,null),(null,null,3)"
63
+
64
+ // 或者你可以指定选择键并指定顺序
65
+ v.objectListToValuesList(values, ["c", "b"]); // "(null,2),(3,3)"
66
+ ```
67
+
68
+ ### 生成 SQL 语句
69
+
70
+ ```ts
71
+ import { Selection, v } from "@asla/yoursql";
72
+
73
+ const searchName = "Bob";
74
+ const s = Selection.from("user", "u")
75
+ .innerJoin("role", "r", "u.id=r.user_id")
76
+ .select({ uid: "u.id", rid: "r.id", example: "u.id||r.id" }) // SELECT u.id AS uid, r.id AS rid u.id||u.id AS example
77
+ .where(`u.name LIKE %${v(searchName)}%`)
78
+ .toString();
79
+ ```
package/dist/mod.d.ts CHANGED
@@ -6,4 +6,10 @@ export * from "./select/selectable.ts";
6
6
  export * from "./select/TableQuery.ts";
7
7
  export * from "./util.ts";
8
8
  export * from "./your_table/mod.ts";
9
+ import { SqlValueFn } from "./sql_value/sql_value.ts";
10
+ /**
11
+ * 默认的 SqlValuesCreator 实列
12
+ * @public
13
+ */
14
+ export declare const v: SqlValueFn;
9
15
  //# sourceMappingURL=mod.d.ts.map
package/dist/mod.js CHANGED
@@ -107,7 +107,12 @@ function getObjectListKeys(objectList, keepUndefinedKey) {
107
107
  * @public
108
108
  * @example
109
109
  * ```ts
110
- *
110
+ * where(['a=1','b=2']) // "\nWHERE a=1 AND b=2"
111
+ * where(['a=1','b=2'],"OR") // "\nWHERE a=1 OR b=2"
112
+ * where("a=1 OR b=2") // "\nWHERE a=1 OR b=2"
113
+ * where(()=>"a=1 OR b=2") // "\nWHERE a=1 AND b=2"
114
+ * where([]) // ""
115
+ * where(undefined) // ""
111
116
  * ```
112
117
  */
113
118
  function where(conditions, type) {
@@ -243,41 +248,14 @@ var _SqlQueryStatement_sql;
243
248
  * @public
244
249
  */
245
250
  class SqlSelectable {
246
- constructor(columns) {
247
- // Reflect.set(this, SQL_SELECTABLE, undefined);
248
- let readonlyColumns;
249
- if (typeof columns[Symbol.iterator] === "function") {
250
- let iterable = columns;
251
- readonlyColumns = [];
252
- let iter = iterable[Symbol.iterator]();
253
- let i = 0;
254
- let item = iter.next();
255
- while (!item.done) {
256
- readonlyColumns[i++] = item.value;
257
- item = iter.next();
258
- }
259
- // readonlyColumns.length = i;
260
- }
261
- else {
262
- let arrayLike = columns;
263
- readonlyColumns = new Array(arrayLike.length);
264
- // readonlyColumns.length = arrayLike.length;
265
- for (let i = 0; i < arrayLike.length; i++) {
266
- readonlyColumns[i] = arrayLike[i];
267
- }
268
- }
269
- this.columns = readonlyColumns;
270
- }
271
251
  }
272
252
  /**
273
253
  * 数据库表
274
254
  * @public
275
255
  */
276
256
  class DbTable extends SqlSelectable {
277
- constructor(name, columns) {
278
- if (!(columns instanceof Array))
279
- columns = Object.keys(columns);
280
- super(columns);
257
+ constructor(name) {
258
+ super();
281
259
  this.name = name;
282
260
  }
283
261
  toSelect() {
@@ -292,14 +270,10 @@ class DbTable extends SqlSelectable {
292
270
  * @public
293
271
  */
294
272
  class SqlQueryStatement extends SqlSelectable {
295
- constructor(sql, columns) {
296
- if (sql instanceof SqlQueryStatement) {
297
- columns = sql.columns;
298
- sql = __classPrivateFieldGet(sql, _SqlQueryStatement_sql, "f");
299
- }
300
- super(columns);
273
+ constructor(sql) {
274
+ super();
301
275
  _SqlQueryStatement_sql.set(this, void 0);
302
- __classPrivateFieldSet(this, _SqlQueryStatement_sql, sql, "f");
276
+ __classPrivateFieldSet(this, _SqlQueryStatement_sql, sql.toString(), "f");
303
277
  }
304
278
  toString() {
305
279
  return __classPrivateFieldGet(this, _SqlQueryStatement_sql, "f");
@@ -310,21 +284,13 @@ class SqlQueryStatement extends SqlSelectable {
310
284
  }
311
285
  _SqlQueryStatement_sql = new WeakMap();
312
286
 
313
- var _SqlRaw_value, _YourValuesAs_asName, _YourValuesAs_valuesStr, _YourValuesAs_sql;
287
+ var _SqlValuesCreator_map, _YourValuesAs_asName, _YourValuesAs_valuesStr, _YourValuesAs_sql;
314
288
  /**
315
- * SQL 原始字符对象
289
+ * SQL 原始字符类。可以使用 String 类代替,这只是为了推断类型
316
290
  * @public
317
291
  */
318
- class SqlRaw {
319
- constructor(value) {
320
- _SqlRaw_value.set(this, void 0);
321
- __classPrivateFieldSet(this, _SqlRaw_value, value, "f");
322
- }
323
- toString() {
324
- return __classPrivateFieldGet(this, _SqlRaw_value, "f");
325
- }
292
+ class SqlRaw extends String {
326
293
  }
327
- _SqlRaw_value = new WeakMap();
328
294
  /**
329
295
  * SQL value 生成器
330
296
  * @public
@@ -346,28 +312,43 @@ class SqlValuesCreator {
346
312
  /**
347
313
  * @param map - 自定义对象转换
348
314
  */
349
- constructor(map = new Map()) {
350
- this.map = map;
315
+ constructor(map) {
316
+ _SqlValuesCreator_map.set(this, void 0);
317
+ __classPrivateFieldSet(this, _SqlValuesCreator_map, new Map(map), "f");
351
318
  }
352
- /** 设置转换器 */
353
- setTransformer(type, transformer) {
354
- if (!transformer)
355
- this.map.delete(type);
356
- else
357
- this.map.set(type, transformer);
319
+ setTransformer(type_map, encoder) {
320
+ if (typeof type_map === "function") {
321
+ if (encoder)
322
+ __classPrivateFieldGet(this, _SqlValuesCreator_map, "f").set(type_map, encoder);
323
+ else
324
+ __classPrivateFieldGet(this, _SqlValuesCreator_map, "f").delete(type_map);
325
+ }
326
+ else {
327
+ for (const [type, encoder] of type_map) {
328
+ if (typeof type === "function" && typeof encoder === "function") {
329
+ __classPrivateFieldGet(this, _SqlValuesCreator_map, "f").set(type, encoder);
330
+ }
331
+ }
332
+ }
358
333
  }
359
- /** 将 JS 对象转为 SQL 的字符值的形式 。 undefined 将被转换为 DEFAULT */
360
- toSqlStr(value, expectType) {
334
+ /**
335
+ * JS 对象转为 SQL 的字符值的形式 。 undefined 将被转换为 DEFAULT
336
+ * ```ts
337
+ * const v=SqlValuesCreator.create()
338
+ * v() 和 v.toSqlStr() 是等价的
339
+ * ```
340
+ */
341
+ toSqlStr(value, assertType) {
361
342
  let basicType;
362
- if (expectType) {
363
- if (typeof expectType === "function") {
364
- let type = this.map.get(expectType);
343
+ if (assertType) {
344
+ if (typeof assertType === "function") {
345
+ let type = __classPrivateFieldGet(this, _SqlValuesCreator_map, "f").get(assertType);
365
346
  if (!type)
366
347
  throw new Error("类型不存在");
367
348
  return type.call(this, value);
368
349
  }
369
350
  else {
370
- basicType = expectType;
351
+ basicType = assertType;
371
352
  }
372
353
  }
373
354
  else
@@ -384,7 +365,7 @@ class SqlValuesCreator {
384
365
  case "object": {
385
366
  if (value === null)
386
367
  return "NULL";
387
- if (value instanceof SqlRaw)
368
+ if (value instanceof String)
388
369
  return value.toString();
389
370
  return this.getObjectType(value).call(this, value);
390
371
  }
@@ -398,9 +379,9 @@ class SqlValuesCreator {
398
379
  }
399
380
  /** 获取值对应的 SqlValueEncoder */
400
381
  getObjectType(value) {
401
- for (const Class of this.map.keys()) {
382
+ for (const Class of __classPrivateFieldGet(this, _SqlValuesCreator_map, "f").keys()) {
402
383
  if (value instanceof Class)
403
- return this.map.get(Class);
384
+ return __classPrivateFieldGet(this, _SqlValuesCreator_map, "f").get(Class);
404
385
  }
405
386
  return this.defaultObject;
406
387
  }
@@ -518,15 +499,16 @@ class SqlValuesCreator {
518
499
  return new YourValuesAs(insertKeys, asName, valuesStr.join(",\n"));
519
500
  }
520
501
  }
502
+ _SqlValuesCreator_map = new WeakMap();
521
503
  class YourValuesAs extends SqlSelectable {
522
504
  constructor(columns, asName, valuesStr) {
523
- super(columns);
505
+ super();
524
506
  _YourValuesAs_asName.set(this, void 0);
525
507
  _YourValuesAs_valuesStr.set(this, void 0);
526
508
  _YourValuesAs_sql.set(this, void 0);
527
509
  __classPrivateFieldSet(this, _YourValuesAs_asName, asName, "f");
528
510
  __classPrivateFieldSet(this, _YourValuesAs_valuesStr, valuesStr, "f");
529
- __classPrivateFieldSet(this, _YourValuesAs_sql, `(VALUES\n${__classPrivateFieldGet(this, _YourValuesAs_valuesStr, "f")})\nAS ${__classPrivateFieldGet(this, _YourValuesAs_asName, "f")}(${this.columns.join(",")})`, "f");
511
+ __classPrivateFieldSet(this, _YourValuesAs_sql, `(VALUES\n${__classPrivateFieldGet(this, _YourValuesAs_valuesStr, "f")})\nAS ${__classPrivateFieldGet(this, _YourValuesAs_asName, "f")}(${columns.join(",")})`, "f");
530
512
  }
531
513
  toSelect() {
532
514
  return __classPrivateFieldGet(this, _YourValuesAs_sql, "f");
@@ -579,11 +561,11 @@ const pgSqlTransformer = new Map([
579
561
 
580
562
  var _Selection_instances, _a, _Selection_sql, _Selection_join;
581
563
  class AfterSelectImpl extends SqlQueryStatement {
582
- constructor(sql, columns) {
583
- super(sql, columns);
564
+ constructor(sql) {
565
+ super(sql);
584
566
  }
585
567
  where(param) {
586
- return new AfterSelectImpl(this.toString() + where(param), this.columns);
568
+ return new AfterSelectImpl(this.toString() + where(param));
587
569
  }
588
570
  groupBy(columns) {
589
571
  let sql = this.toString();
@@ -591,13 +573,13 @@ class AfterSelectImpl extends SqlQueryStatement {
591
573
  sql += " GROUP BY " + columns;
592
574
  else
593
575
  sql += " GROUP BY " + columns.join(",");
594
- return new AfterSelectImpl(sql, this.columns);
576
+ return new AfterSelectImpl(sql);
595
577
  }
596
578
  having(param) {
597
- return new AfterSelectImpl(this.toString() + having(param), this.columns);
579
+ return new AfterSelectImpl(this.toString() + having(param));
598
580
  }
599
581
  orderBy(param) {
600
- return new AfterSelectImpl(this.toString() + orderBy(param), this.columns);
582
+ return new AfterSelectImpl(this.toString() + orderBy(param));
601
583
  }
602
584
  limit(limit, offset) {
603
585
  let sql = this.toString();
@@ -605,10 +587,12 @@ class AfterSelectImpl extends SqlQueryStatement {
605
587
  sql += "\nLIMIT " + limit;
606
588
  if (offset)
607
589
  sql += "\nOFFSET " + offset;
608
- return new SqlQueryStatement(sql, Array.from(this.columns));
590
+ return new SqlQueryStatement(sql);
609
591
  }
610
592
  }
611
593
  function fromAs(selectable, as) {
594
+ if (typeof selectable === "function")
595
+ selectable = selectable();
612
596
  let sql = typeof selectable === "string" ? selectable : selectable.toSelect();
613
597
  if (as)
614
598
  sql += " AS " + as;
@@ -649,14 +633,11 @@ class Selection {
649
633
  return new _a(__classPrivateFieldGet(this, _Selection_sql, "f") + "," + fromAs(selectable, as));
650
634
  }
651
635
  select(columnsIn) {
652
- let columns = [];
653
636
  if (typeof columnsIn === "function")
654
637
  columnsIn = columnsIn();
655
- if (typeof columnsIn === "object")
656
- columns = Object.keys(columnsIn);
657
638
  let sql = "SELECT " + selectColumns(columnsIn);
658
639
  sql += "\n" + this.toString();
659
- return new AfterSelectImpl(sql, columns);
640
+ return new AfterSelectImpl(sql);
660
641
  }
661
642
  }
662
643
  _a = Selection, _Selection_sql = new WeakMap(), _Selection_instances = new WeakSet(), _Selection_join = function _Selection_join(type, selectable, as, on) {
@@ -669,8 +650,8 @@ _a = Selection, _Selection_sql = new WeakMap(), _Selection_instances = new WeakS
669
650
 
670
651
  /** @public */
671
652
  class DbTableQuery extends DbTable {
672
- constructor(name, columns, statement) {
673
- super(name, columns);
653
+ constructor(name, statement) {
654
+ super(name);
674
655
  this.statement = statement;
675
656
  }
676
657
  fromAs(as) {
@@ -679,89 +660,127 @@ class DbTableQuery extends DbTable {
679
660
  select(columns, as) {
680
661
  return this.fromAs(as).select(columns);
681
662
  }
682
- insert(values, option) {
683
- let insertCol;
663
+ insert(values, columns_option, option) {
664
+ if (typeof values === "function")
665
+ values = values();
666
+ let columnStr;
684
667
  let valuesStr;
685
- if (values instanceof Array) {
686
- if (values.length === 0)
687
- throw new Error("值不能为空");
688
- insertCol = Array.from(getObjectListKeys(values));
689
- valuesStr = `VALUES\n${this.statement.objectListToValuesList(values, insertCol)}`;
668
+ if (typeof values === "string") {
669
+ valuesStr = values;
670
+ if (typeof columns_option === "string")
671
+ columnStr = columns_option;
672
+ else if (columns_option instanceof Array) {
673
+ if (columns_option.length === 0)
674
+ throw new Error("插入列为空");
675
+ columnStr = columns_option.join(",");
676
+ }
677
+ else
678
+ throw new Error("当 values 为 string 类型时,必须指定 columns");
690
679
  }
691
- else if (values instanceof SqlQueryStatement) {
692
- // todo 验证 values.columns 和 this.columns 是否匹配
693
- valuesStr = values.toString();
694
- insertCol = values.columns;
680
+ else {
681
+ let insertCol;
682
+ option = columns_option;
683
+ if (typeof values === "object") {
684
+ if (values instanceof Array) {
685
+ if (values.length === 0)
686
+ throw new Error("值不能为空");
687
+ insertCol = Array.from(getObjectListKeys(values));
688
+ valuesStr = `VALUES\n${this.statement.objectListToValuesList(values, insertCol)}`;
689
+ }
690
+ else if (values instanceof SqlQueryStatement) {
691
+ // todo 验证 values.columns 和 this.columns 是否匹配
692
+ valuesStr = values.toString();
693
+ insertCol = values.columns;
694
+ }
695
+ else {
696
+ insertCol = Object.keys(values);
697
+ valuesStr = `VALUES\n(${this.statement.objectToValues(values, insertCol)})`;
698
+ }
699
+ }
700
+ else
701
+ throw new Error("values 应该是 Array 或 TableQuery 类型");
702
+ if (insertCol.length === 0)
703
+ throw new Error("插入列不能为空");
704
+ columnStr = insertCol.join(",");
695
705
  }
696
- else
697
- throw new Error("values 应该是 Array 或 TableQuery 类型");
698
- if (insertCol.length === 0)
699
- throw new Error("插入列不能为空");
700
- let sql = `INSERT INTO ${this.name} (${insertCol.join(",")})\n${valuesStr}`;
706
+ let sql = `INSERT INTO ${this.name} (${columnStr})\n${valuesStr}`;
701
707
  if (option) {
702
- const { updateValues, conflict, where } = option;
708
+ let { updateValues, conflict, where: inputWhere } = option;
703
709
  if (conflict) {
704
- sql += `\nON CONFLICT (${conflict.join(",")})`;
710
+ if (typeof conflict !== "string")
711
+ conflict = conflict.join(",");
712
+ sql += `\nON CONFLICT (${conflict})`;
713
+ if (typeof updateValues === "function")
714
+ updateValues = updateValues();
705
715
  if (updateValues) {
706
716
  const updateKey = Object.entries(updateValues);
707
717
  sql += `\nDO UPDATE SET\n${updateKey.map(([key, v = "EXCLUDED." + key]) => key + " = " + v).join(",\n")}`;
708
718
  }
709
719
  else
710
720
  sql += "DO NOTHING";
711
- if (where)
712
- sql += "\nWHERE " + where;
721
+ sql += where(inputWhere);
713
722
  }
714
723
  }
715
724
  return sql;
716
725
  }
717
- insertWithResult(values, returns, option) {
718
- let sql = this.insert(values, option);
719
- return genRetuningSql(sql, returns, values instanceof SqlQueryStatement ? values.columns : this.columns);
726
+ insertWithResult(values, returns, columns, option) {
727
+ let sql = this.insert(values, columns, option);
728
+ return genRetuningSql(sql, returns);
720
729
  }
730
+ /**
731
+ * @example
732
+ * ```ts
733
+ * table.update("age=3, name='hi'") // "UPDATE table SET age=3, name='hi'"
734
+ * table.update({age:3, name:"hi"}) // "UPDATE table SET age=3, name='hi'"
735
+ * ```
736
+ */
721
737
  update(values, option = {}) {
722
- const updateKey = Object.entries(values);
723
- if (updateKey.length === 0)
724
- throw new Error("值不能为空");
725
- let setList = [];
726
- for (const [k, v] of updateKey) {
727
- if (v === undefined)
728
- continue;
729
- setList.push(k + " = " + this.statement.toSqlStr(v));
738
+ if (typeof values === "function")
739
+ values = values();
740
+ let setStr;
741
+ if (typeof values === "string")
742
+ setStr = values;
743
+ else {
744
+ const updateKey = Object.entries(values);
745
+ let setList = [];
746
+ for (const [k, v] of updateKey) {
747
+ if (v === undefined)
748
+ continue;
749
+ setList.push(k + " = " + this.statement.toSqlStr(v));
750
+ }
751
+ setStr = setList.join(",\n");
730
752
  }
731
- let sql = `UPDATE ${this.name}\nSET ${setList.join(",\n")}`;
732
- if (option.where)
733
- sql += where(option.where);
753
+ if (!setStr)
754
+ throw new Error("值不能为空");
755
+ let sql = `UPDATE ${this.name}\nSET ${setStr}`;
756
+ sql += where(option.where);
734
757
  return sql;
735
758
  }
736
759
  updateWithResult(values, returns, option) {
737
760
  let sql = this.update(values, option);
738
- return genRetuningSql(sql, returns, values instanceof SqlQueryStatement ? values.columns : this.columns);
761
+ return genRetuningSql(sql, returns);
739
762
  }
740
763
  delete(option = {}) {
741
764
  let sql = "DELETE FROM " + this.name;
742
- if (option.where)
743
- sql += where(option.where);
765
+ sql += where(option.where);
744
766
  return sql;
745
767
  }
746
768
  deleteWithResult(returns = "*", option) {
747
769
  let sql = this.delete(option);
748
- return genRetuningSql(sql, returns, this.columns);
770
+ return genRetuningSql(sql, returns);
749
771
  }
750
772
  }
751
- function genRetuningSql(sql, returns, tableColumns) {
773
+ function genRetuningSql(sql, returns) {
752
774
  let columnsStr;
753
- let columns;
754
775
  if (returns === "*") {
755
- columns = tableColumns;
756
776
  columnsStr = "*";
757
777
  }
758
778
  else {
759
779
  const res = selectColumnsOrTable(returns);
760
780
  columnsStr = res.sqlColumns;
761
- columns = res.columns;
762
781
  }
763
782
  sql += "\nRETURNING " + columnsStr;
764
- return new SqlQueryStatement(sql, columns);
783
+ return new SqlQueryStatement(sql);
765
784
  }
766
785
 
767
786
  /**
@@ -915,8 +934,9 @@ function getErrStr(expect, actual) {
915
934
  */
916
935
  class YourTable extends DbTableQuery {
917
936
  constructor(name, define, sqlValue) {
918
- super(name, Object.keys(define), sqlValue);
937
+ super(name, sqlValue);
919
938
  this.define = define;
939
+ this.columns = Object.keys(define);
920
940
  }
921
941
  getColumnMeta(name) {
922
942
  return Reflect.get(this.define, name);
@@ -935,4 +955,10 @@ class YourTable extends DbTableQuery {
935
955
  }
936
956
  }
937
957
 
938
- export { ColumnMeta, CustomDbType, DbTable, DbTableQuery, Selection, SqlQueryStatement, SqlRaw, SqlSelectable, SqlValuesCreator, TypeChecker, YourTable, YourTypeMap, getObjectListKeys, having, orderBy, pgSqlTransformer, selectColumns, where };
958
+ /**
959
+ * 默认的 SqlValuesCreator 实列
960
+ * @public
961
+ */
962
+ const v = SqlValuesCreator.create(pgSqlTransformer);
963
+
964
+ export { ColumnMeta, CustomDbType, DbTable, DbTableQuery, Selection, SqlQueryStatement, SqlRaw, SqlSelectable, SqlValuesCreator, TypeChecker, YourTable, YourTypeMap, getObjectListKeys, having, orderBy, pgSqlTransformer, selectColumns, v, where };
@@ -2,11 +2,11 @@ import { SqlValuesCreator, SqlRaw } from "../sql_value/sql_value.ts";
2
2
  import { ColumnsSelected, SelectColumns, UpdateRowValue, TableType } from "./type.ts";
3
3
  import { CurrentWhere, Selection } from "./select.ts";
4
4
  import { DbTable, SqlQueryStatement } from "./selectable.ts";
5
- import { ConditionParam } from "../util.ts";
5
+ import { ConditionParam, Constructable } from "../util.ts";
6
6
  /** @public */
7
7
  export declare class DbTableQuery<T extends TableType = Record<string, any>, C extends TableType = Partial<T>> extends DbTable<T> {
8
8
  private statement;
9
- constructor(name: string, columns: readonly string[], statement: SqlValuesCreator);
9
+ constructor(name: string, statement: SqlValuesCreator);
10
10
  fromAs(as?: string): Selection;
11
11
  /** 选择单表全部列 */
12
12
  select(columns: "*", as?: string): CurrentWhere<T>;
@@ -15,37 +15,57 @@ export declare class DbTableQuery<T extends TableType = Record<string, any>, C e
15
15
  * @param columns - 对象选择
16
16
  */
17
17
  select<R extends {
18
- [key in keyof T]?: string | boolean;
19
- } | Record<string, string>>(columns: R | (() => R), as?: string): CurrentWhere<{
20
- [key in keyof R]: R[key] extends boolean ? key extends keyof T ? T[key] : unknown : R[key] extends keyof T ? T[R[key]] : unknown;
18
+ [key in keyof T]?: boolean;
19
+ }>(columns: Constructable<R>, as?: string): CurrentWhere<{
20
+ [key in keyof R]: key extends keyof T ? T[key] : unknown;
21
21
  }>;
22
22
  /** 选择单表- 所有类型 */
23
- select<R extends {}>(columns: string | {
23
+ select<R extends {}>(columns: Constructable<{
24
24
  [key in keyof R]?: key extends keyof T ? string | boolean : string;
25
- } | (() => string | {
26
- [key in keyof R]?: key extends keyof T ? string | boolean : string;
27
- }), as?: string): CurrentWhere<R>;
28
- insert(values: C[] | SqlQueryStatement<C>, option?: InsertOption<T>): string;
29
- insertWithResult<R extends ColumnsSelected<T>>(values: C[] | SqlQueryStatement<C>, returns: R, option?: InsertOption<T>): SqlQueryStatement<SelectColumns<T, R>>;
30
- update(values: UpdateRowValue<T>, option?: UpdateOption): string;
31
- updateWithResult<R extends ColumnsSelected<T>>(values: UpdateRowValue<T>, returns: R, option?: UpdateOption): SqlQueryStatement<SelectColumns<T, R>>;
25
+ } | string>, as?: string): CurrentWhere<R>;
26
+ /**
27
+ * @example
28
+ * ```ts
29
+ * table.insert({age:18, name:"hi"}) // INSERT INTO table(age,name) VALUES (18, 'hi')
30
+ * table.insert([{age:18, name:"hi"}, {age:17, name:"hh"}]) // INSERT INTO table(age,name) VALUES(18, 'hi'), (17, 'hh')
31
+ * ```
32
+ */
33
+ insert(values: Constructable<C | C[]>, option?: InsertOption<T>): string;
34
+ /**
35
+ * @example
36
+ * ```ts
37
+ * table.insert("VALUES (18, 'hi'), (17, 'hh')", ["age","name"]) // INSERT INTO table(age,name) VALUES(18, 'hi'), (17, 'hh')
38
+ * ```
39
+ */
40
+ insert(values: Constructable<string>, columns: string[], option?: InsertOption<T>): string;
41
+ insertWithResult<R extends ColumnsSelected<T>>(values: Constructable<C | C[]>, returns: R, option?: InsertOption<T>): SqlQueryStatement<SelectColumns<T, R>>;
42
+ insertWithResult<R extends ColumnsSelected<T>>(values: Constructable<string>, returns: R, columns: string | string[], option?: InsertOption<T>): SqlQueryStatement<SelectColumns<T, R>>;
43
+ /**
44
+ * @example
45
+ * ```ts
46
+ * table.update("age=3, name='hi'") // "UPDATE table SET age=3, name='hi'"
47
+ * table.update({age:3, name:"hi"}) // "UPDATE table SET age=3, name='hi'"
48
+ * ```
49
+ */
50
+ update(values: Constructable<UpdateRowValue<T> | string>, option?: UpdateOption): string;
51
+ updateWithResult<R extends ColumnsSelected<T>>(values: Constructable<UpdateRowValue<T>>, returns: R, option?: UpdateOption): SqlQueryStatement<SelectColumns<T, R>>;
32
52
  delete(option?: DeleteOption): string;
33
53
  deleteWithResult<R extends ColumnsSelected<T>>(returns?: ColumnsSelected<T> | "*", option?: DeleteOption): SqlQueryStatement<SelectColumns<T, R>>;
34
54
  }
35
55
  /** @public */
36
56
  export interface InsertOption<T extends object> {
37
- conflict?: (keyof T)[];
38
- updateValues?: {
57
+ conflict?: (keyof T)[] | string;
58
+ updateValues?: Constructable<{
39
59
  [key in keyof T]?: undefined | SqlRaw | T[key];
40
- };
41
- where?: ConditionParam;
60
+ } | string | void>;
61
+ where?: Constructable<ConditionParam | void>;
42
62
  }
43
63
  /** @public */
44
64
  export interface UpdateOption {
45
- where?: ConditionParam;
65
+ where?: Constructable<ConditionParam | void>;
46
66
  }
47
67
  /** @public */
48
68
  export interface DeleteOption {
49
- where?: ConditionParam;
69
+ where?: Constructable<ConditionParam | void>;
50
70
  }
51
71
  //# sourceMappingURL=TableQuery.d.ts.map
@@ -1,5 +1,5 @@
1
- import { ColumnsSelectAs } from "./type.ts";
2
- export declare function selectColumnsOrTable(columns: ColumnsSelectAs<any> | string[]): {
1
+ import { Constructable } from "../util.ts";
2
+ export declare function selectColumnsOrTable(columns: Record<string, boolean | string> | string[]): {
3
3
  columns: string[];
4
4
  sqlColumns: string;
5
5
  };
@@ -7,6 +7,6 @@ type ConditionParam = string | string[];
7
7
  /**
8
8
  * 生成条件语句
9
9
  */
10
- export declare function condition(conditions?: ConditionParam | (() => ConditionParam | void), type?: "AND" | "OR"): string;
10
+ export declare function condition(conditions?: Constructable<ConditionParam | void>, type?: "AND" | "OR"): string;
11
11
  export {};
12
12
  //# sourceMappingURL=_statement.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { SqlSelectable, SqlQueryStatement } from "./selectable.ts";
2
- import { OrderByParam, ConditionParam, SelectParam } from "../util.ts";
2
+ import { OrderByParam, ConditionParam, SelectParam, Constructable } from "../util.ts";
3
3
  import type { TableType } from "./type.ts";
4
4
  /** @public */
5
5
  export interface CurrentLimit<T extends TableType> extends SqlQueryStatement<T> {
@@ -7,11 +7,11 @@ export interface CurrentLimit<T extends TableType> extends SqlQueryStatement<T>
7
7
  }
8
8
  /** @public */
9
9
  export interface CurrentOrderBy<T extends TableType> extends CurrentLimit<T> {
10
- orderBy(param: OrderByParam | (() => OrderByParam | void)): CurrentLimit<T>;
10
+ orderBy(param: Constructable<OrderByParam | void>): CurrentLimit<T>;
11
11
  }
12
12
  /** @public */
13
13
  export interface CurrentHaving<T extends TableType> extends CurrentOrderBy<T> {
14
- having(param: ConditionParam | (() => ConditionParam | void)): CurrentLimit<T>;
14
+ having(param: Constructable<ConditionParam | void>): CurrentLimit<T>;
15
15
  }
16
16
  /** @public */
17
17
  export interface CurrentGroupBy<T extends TableType> extends CurrentOrderBy<T> {
@@ -19,21 +19,21 @@ export interface CurrentGroupBy<T extends TableType> extends CurrentOrderBy<T> {
19
19
  }
20
20
  /** @public */
21
21
  export interface CurrentWhere<T extends TableType> extends CurrentGroupBy<T> {
22
- where(param: ConditionParam | (() => ConditionParam | void)): CurrentGroupBy<T>;
22
+ where(param: Constructable<ConditionParam | void>): CurrentGroupBy<T>;
23
23
  }
24
24
  /** @public */
25
25
  export declare class Selection {
26
26
  #private;
27
- static from(selectable: SqlSelectable<any> | string, as?: string): Selection;
28
- constructor(selectable: SqlSelectable<any> | string, as?: string);
27
+ static from(selectable: Constructable<SqlSelectable<any> | string>, as?: string): Selection;
28
+ constructor(selectable: Constructable<SqlSelectable<any> | string>, as?: string);
29
29
  toString(): string;
30
- fullJoin(selectable: SqlSelectable<any>, as: string | undefined, on: ConditionParam | (() => ConditionParam)): Selection;
31
- innerJoin(selectable: SqlSelectable<any>, as: string | undefined, on: ConditionParam | (() => ConditionParam)): Selection;
32
- leftJoin(selectable: SqlSelectable<any>, as: string | undefined, on: ConditionParam | (() => ConditionParam)): Selection;
33
- rightJoin(selectable: SqlSelectable<any>, as: string | undefined, on: ConditionParam | (() => ConditionParam)): Selection;
34
- naturalJoin(selectable: SqlSelectable<any>, as?: string | undefined): Selection;
35
- crossJoin(selectable: SqlSelectable<any>, as?: string | undefined): Selection;
36
- from(selectable: SqlSelectable<any> | string, as?: string): Selection;
30
+ fullJoin(selectable: Constructable<SqlSelectable<any> | string>, as: string | undefined, on: Constructable<ConditionParam>): Selection;
31
+ innerJoin(selectable: Constructable<SqlSelectable<any> | string>, as: string | undefined, on: Constructable<ConditionParam>): Selection;
32
+ leftJoin(selectable: Constructable<SqlSelectable<any> | string>, as: string | undefined, on: Constructable<ConditionParam>): Selection;
33
+ rightJoin(selectable: Constructable<SqlSelectable<any> | string>, as: string | undefined, on: Constructable<ConditionParam>): Selection;
34
+ naturalJoin(selectable: Constructable<SqlSelectable<any> | string>, as?: string | undefined): Selection;
35
+ crossJoin(selectable: Constructable<SqlSelectable<any> | string>, as?: string | undefined): Selection;
36
+ from(selectable: Constructable<SqlSelectable<any> | string>, as?: string): Selection;
37
37
  /** 选择全部列 */
38
38
  select<T extends TableType = TableType>(columns: "*"): CurrentWhere<T>;
39
39
  /**
@@ -43,7 +43,7 @@ export declare class Selection {
43
43
  * selection.select("t.age, count(*) AS c") // SELECT t.age,count(*) AS c FROM ...
44
44
  * ```
45
45
  */
46
- select<T extends TableType = TableType>(columns: string): CurrentWhere<T>;
46
+ select<T extends TableType = TableType>(columns: Constructable<string>): CurrentWhere<T>;
47
47
  /**
48
48
  * 通过 object 选择 列
49
49
  * @example
@@ -51,11 +51,9 @@ export declare class Selection {
51
51
  * selection.select({"age":true, c:"count(*)"}) // SELECT age,count(*) AS c FROM ...
52
52
  * ```
53
53
  */
54
- select<T extends TableType>(columns: {
54
+ select<T extends TableType>(columns: Constructable<{
55
55
  [key in keyof T]: string | boolean;
56
- } | (() => {
57
- [key in keyof T]: string | boolean;
58
- })): CurrentWhere<T>;
59
- select(columns: SelectParam | (() => SelectParam)): CurrentWhere<TableType>;
56
+ }>): CurrentWhere<T>;
57
+ select(columns: Constructable<SelectParam>): CurrentWhere<TableType>;
60
58
  }
61
59
  //# sourceMappingURL=select.d.ts.map
@@ -11,9 +11,6 @@ declare const SQL_SELECTABLE: unique symbol;
11
11
  * @public
12
12
  */
13
13
  export declare abstract class SqlSelectable<T extends TableType> {
14
- constructor(columns: ArrayLike<string> | Iterable<string>);
15
- /** 结果列 */
16
- readonly columns: readonly string[];
17
14
  /**
18
15
  * 转成子选择语句, 你可以使用 select form xxx 选择
19
16
  * 如果是 table 则是 table name
@@ -31,7 +28,7 @@ export declare abstract class SqlSelectable<T extends TableType> {
31
28
  */
32
29
  export declare class DbTable<T extends TableType> extends SqlSelectable<T> {
33
30
  readonly name: string;
34
- constructor(name: string, columns: readonly (keyof T)[]);
31
+ constructor(name: string);
35
32
  toSelect(): string;
36
33
  toString(): string;
37
34
  }
@@ -41,8 +38,7 @@ export declare class DbTable<T extends TableType> extends SqlSelectable<T> {
41
38
  */
42
39
  export declare class SqlQueryStatement<T extends TableType = TableType> extends SqlSelectable<T> {
43
40
  #private;
44
- constructor(sql: string, columns: readonly string[]);
45
- constructor(sql: SqlQueryStatement);
41
+ constructor(sql: string | SqlQueryStatement);
46
42
  toString(): string;
47
43
  toSelect(): string;
48
44
  }
@@ -18,25 +18,22 @@ export type PickColumn<T extends {
18
18
  export type UpdateRowValue<T extends object> = {
19
19
  [key in keyof T]?: T[key] | SqlRaw;
20
20
  };
21
- /**
22
- * 选择列并重命名
23
- * @public
24
- */
25
- export type ColumnsSelectAs<T extends TableType> = {
26
- [key in keyof T]?: boolean | string;
27
- };
28
21
  /** @public */
29
22
  export type OrderValue = "ASC" | "DESC";
30
23
  /**
31
24
  * 表的选择参数
32
25
  * @public
33
26
  */
34
- export type ColumnsSelected<T extends TableType> = ColumnsSelectAs<T> | "*";
27
+ export type ColumnsSelected<T extends TableType> = {
28
+ [key in keyof T]?: boolean | string;
29
+ } | "*";
35
30
  /**
36
31
  * 从一个表格选择列,生成新的表格类型
37
32
  * @public
38
33
  */
39
- export type SelectColumns<T extends TableType, R extends ColumnsSelected<T>> = R extends "*" ? T : R extends ColumnsSelectAs<T> ? {
34
+ export type SelectColumns<T extends TableType, R extends ColumnsSelected<T>> = R extends "*" ? T : R extends {
35
+ [key in keyof T]?: boolean | string;
36
+ } ? {
40
37
  [key in keyof T as R[key] extends true ? key : StringOnly<R[key]>]: T[key];
41
38
  } : never;
42
39
  type StringOnly<T> = T extends string ? T : never;
@@ -1,33 +1,34 @@
1
1
  import { SqlSelectable } from "../select/selectable.ts";
2
2
  declare const SQL_RAW: unique symbol;
3
3
  /**
4
- * SQL 原始字符对象
4
+ * SQL 原始字符类。可以使用 String 类代替,这只是为了推断类型
5
5
  * @public
6
6
  */
7
- export declare class SqlRaw<T = any> {
8
- #private;
9
- constructor(value: string);
10
- toString(): string;
7
+ export declare class SqlRaw<T = any> extends String {
11
8
  /** 保留以推断类型 */
12
9
  protected [SQL_RAW]: T;
13
10
  }
14
- /** @public */
11
+ /** @public js 对象到编码函数的映射*/
15
12
  export type JsObjectMapSql = Map<new (...args: any[]) => any, SqlValueEncoder>;
16
- /** @public */
13
+ /** @public 将 js 值转为 SQl 字符串的函数*/
17
14
  export type SqlValueEncoder<T = any> = (this: SqlValuesCreator, value: T) => string;
18
- /** @public */
15
+ /** @public 断言类型 */
19
16
  export type ManualType = "bigint" | "number" | "string" | "boolean" | "object" | (new (...args: any[]) => any);
20
17
  /** @public */
21
- export interface SqlValueFn {
22
- /** 将 JS 对象转为 SQL 的字符值的形式 。 undefined 将被转换为 DEFAULT */
23
- (value: any, expectType?: ManualType): string;
24
- }
18
+ export type SqlValueFn = SqlValuesCreator & {
19
+ /**
20
+ * 安全将 JS 对象转为 SQL 的字符值的形式,可避免 SQL 注入。
21
+ * undefined 将被转换为 DEFAULT
22
+ */
23
+ (value: any, assertType?: ManualType): string;
24
+ };
25
25
  /**
26
26
  * SQL value 生成器
27
27
  * @public
28
28
  */
29
29
  export declare class SqlValuesCreator {
30
- static create(map?: JsObjectMapSql): SqlValuesCreator & SqlValueFn;
30
+ #private;
31
+ static create(map?: JsObjectMapSql): SqlValueFn;
31
32
  /**
32
33
  * 将字符串转为 SQL 的字符串值的形式(单引号会被转义)。
33
34
  * @example 输入 a'b'c , 返回 a''b''c.
@@ -38,15 +39,21 @@ export declare class SqlValuesCreator {
38
39
  */
39
40
  constructor(map?: JsObjectMapSql);
40
41
  /** 设置转换器 */
41
- setTransformer<T>(type: new (...args: any[]) => T, transformer?: SqlValueEncoder): void;
42
- private readonly map;
43
- /** 将 JS 对象转为 SQL 的字符值的形式 。 undefined 将被转换为 DEFAULT */
44
- toSqlStr(value: any, expectType?: ManualType): string;
42
+ setTransformer(type: new (...args: any[]) => any, encoder?: SqlValueEncoder): void;
43
+ setTransformer(map: JsObjectMapSql): void;
44
+ /**
45
+ * JS 对象转为 SQL 的字符值的形式 。 undefined 将被转换为 DEFAULT
46
+ * ```ts
47
+ * const v=SqlValuesCreator.create()
48
+ * v() 和 v.toSqlStr() 是等价的
49
+ * ```
50
+ */
51
+ toSqlStr(value: any, assertType?: ManualType): string;
45
52
  /** 获取值对应的 SqlValueEncoder */
46
53
  getObjectType(value: object): SqlValueEncoder;
47
54
  protected defaultObject(value: object): string;
48
55
  /**
49
- * 将对象列表转为 SQL 的 VALUES
56
+ * 将对象列表转为 SQL 的 VALUES
50
57
  * @example 返回示例: " (...),(...) "
51
58
  * @param keys - 选择的键。如果指定了 keys, 值为 undefined 的属性将自动填充为 null; 如果未指定 keys,将选择 objectList 所有不是 undefined 项的键的并集
52
59
  */
package/dist/util.d.ts CHANGED
@@ -6,22 +6,29 @@ import { OrderValue } from "./select/type.ts";
6
6
  */
7
7
  export declare function getObjectListKeys(objectList: any[], keepUndefinedKey?: boolean): Set<string>;
8
8
  /** @public */
9
+ export type Constructable<T> = T | (() => T);
10
+ /** @public */
9
11
  export type ConditionParam = string | string[];
10
12
  /**
11
13
  * 生成 WHERE 语句
12
14
  * @public
13
15
  * @example
14
16
  * ```ts
15
- *
17
+ * where(['a=1','b=2']) // "\nWHERE a=1 AND b=2"
18
+ * where(['a=1','b=2'],"OR") // "\nWHERE a=1 OR b=2"
19
+ * where("a=1 OR b=2") // "\nWHERE a=1 OR b=2"
20
+ * where(()=>"a=1 OR b=2") // "\nWHERE a=1 AND b=2"
21
+ * where([]) // ""
22
+ * where(undefined) // ""
16
23
  * ```
17
24
  */
18
- export declare function where(conditions?: ConditionParam | (() => ConditionParam | void), type?: "AND" | "OR"): string;
25
+ export declare function where(conditions?: Constructable<ConditionParam | void>, type?: "AND" | "OR"): string;
19
26
  /**
20
27
  *
21
28
  * 生成 HAVING 语句
22
29
  * @public
23
30
  */
24
- export declare function having(conditions?: ConditionParam | (() => ConditionParam | void), type?: "AND" | "OR"): string;
31
+ export declare function having(conditions?: Constructable<ConditionParam | void>, type?: "AND" | "OR"): string;
25
32
  /** @public */
26
33
  export type SelectParam = string | Record<string, string | boolean>;
27
34
  /**
@@ -32,7 +39,7 @@ export type SelectParam = string | Record<string, string | boolean>;
32
39
  * selectColumns("c1,count(*) AS c2,column as c3") // "c1,count(*) AS c2,column as c3"
33
40
  * ```
34
41
  */
35
- export declare function selectColumns(columns: SelectParam | (() => SelectParam)): string;
42
+ export declare function selectColumns(columns: Constructable<SelectParam>): string;
36
43
  /** @public */
37
44
  export type OrderBehavior = {
38
45
  key: string;
@@ -59,5 +66,5 @@ export type OrderByParam = string | (string | OrderBehavior)[] | Record<string,
59
66
  * orderBy({}) // ""
60
67
  * ```
61
68
  */
62
- export declare function orderBy(by?: OrderByParam | void | (() => OrderByParam | void)): string;
69
+ export declare function orderBy(by?: Constructable<OrderByParam | void>): string;
63
70
  //# sourceMappingURL=util.d.ts.map
@@ -10,6 +10,7 @@ import { TypeChecker } from "./checker.ts";
10
10
  export declare class YourTable<T extends TableType = TableType, C extends TableType = T> extends DbTableQuery<T, C> {
11
11
  private define;
12
12
  constructor(name: string, define: TableDefined, sqlValue: SqlValuesCreator);
13
+ readonly columns: readonly string[];
13
14
  getColumnMeta(name: keyof T): ColumnMeta<unknown>;
14
15
  createTypeChecker<T>(keys: readonly string[]): TypeChecker<T>;
15
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asla/yoursql",
3
- "version": "0.5.2",
3
+ "version": "0.6.1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "types": "./dist/mod.d.ts",