@asla/yoursql 0.10.1 → 0.10.2

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.
@@ -4,7 +4,7 @@ import { SqlSelectable } from "./SqlStatement.ts";
4
4
  * 获取对象数组中的 key 的集合
5
5
  * @param keepUndefinedKey - 是否保留值为 undefined 的 key
6
6
  */
7
- export declare function getObjectListKeys(objectList: any[], keepUndefinedKey?: boolean): Set<string>;
7
+ export declare function getObjectListKeys(objectList: readonly any[], keepUndefinedKey?: boolean): Set<string>;
8
8
  /**
9
9
  * 生成条件语句
10
10
  */
@@ -14,7 +14,7 @@ function getObjectListKeys(objectList, keepUndefinedKey) {
14
14
  k = hasKeys[j];
15
15
  if (typeof k !== "string")
16
16
  continue;
17
- if (!keepUndefinedKey && obj[k] === undefined)
17
+ if (obj[k] === undefined)
18
18
  continue;
19
19
  keys.add(k);
20
20
  }
@@ -1,5 +1,6 @@
1
1
  import { pgSqlTransformer } from './sql_value/db_type.js';
2
2
  import { SqlValuesCreator } from './sql_value/sql_value.js';
3
+ export { SqlExplicitValuesStatement } from './sql_value/sql_value.js';
3
4
  export { SqlStatement, SqlStatementDataset, SqlTextStatementDataset } from './SqlStatement.js';
4
5
  export { orderBy, select } from './statement/select.js';
5
6
  export { insertInto } from './statement/insert.js';
@@ -1,5 +1,5 @@
1
1
  import { SqlStatementDataset, SqlTemplate } from "../SqlStatement.ts";
2
- import { AssertJsType, ObjectToValueKeys, SqlValuesTextData } from "./type.ts";
2
+ import { AssertJsType, ColumnToValueConfig, ObjectToValueKeys } from "./type.ts";
3
3
  /** @public js 对象到编码函数的映射*/
4
4
  export type JsObjectMapSql = Map<new (...args: any[]) => any, SqlValueEncoder>;
5
5
  /** @public 将 js 值转为 SQl 字符串的函数*/
@@ -45,20 +45,32 @@ export declare class SqlValuesCreator {
45
45
  /** 获取值对应已定义的类 */
46
46
  getClassType(value: object): undefined | (new (...args: unknown[]) => unknown);
47
47
  protected defaultObject(value: object): string;
48
- /** @deprecated 改用 objectListToValues */
49
- objectListToValuesList<T extends object>(objectList: T[], keys?: ObjectToValueKeys<T>, keepUndefinedKey?: boolean): string;
48
+ /** @deprecated 改用 createImplicitValues */
49
+ objectListToValuesList<T extends object>(objectList: T[], keys?: ObjectToValueKeys<T>): string;
50
+ /** @deprecated 请使用 objectListToValues 代替 */
51
+ objectListToValues<T extends object>(objectList: T[], columns?: ObjectToValueKeys<T>): SqlValuesTextData;
50
52
  /**
51
- * 将对象列表转为 SQL 的 VALUES。与 objectToValues类似。如果设定了 keys 的类型,只会转换第一行的数据。
53
+ * 将对象列表转为 SQL 的 VALUES。如果 objectList 中有某个对象的属性值为 undefined,则会被转换为 "DEFAULT"
52
54
  * @example 返回的文本示例: " (...),(...) "
53
- * @param keys - 选择的键。如果指定了 keys, 值为 undefined 的属性将自动填充为 null; 如果未指定 keys,将选择 objectList 所有不是 undefined 项的键的并集
54
- * @param keepUndefinedKey - 是否保留 undefined 的键。默认值为 false,如果为 true , 数组的某一个字段均为 undefined时,将忽略字段,
55
+ * @param columns - 选择的键。如果指定了 columns, 值为 undefined 的属性将自动填充为 null; 如果未指定 columns,将选择 objectList 所有不是 undefined 项的键的并集
55
56
  */
56
- objectListToValues<T extends object>(objectList: T[], keys?: ObjectToValueKeys<T>, keepUndefinedKey?: boolean): SqlValuesTextData;
57
+ createImplicitValues<T extends object>(objectList: T, columns?: ObjectToValueKeys<T>): SqlValuesTextData;
58
+ createImplicitValues<T extends object>(objectList: T[], columns?: ObjectToValueKeys<T>): SqlValuesTextData;
59
+ /**
60
+ * 将对象列表转为 SQL 的 VALUES。如果 objectList 中有某个对象的属性值为 undefined,则会被转换为 "NULL"
61
+ * @example 返回的文本示例: " (...),(...) "
62
+ * @param columns - 选择的键。
63
+ */
64
+ createExplicitValues<T extends object>(objectList: T, columns?: ObjectToValueKeys<T>): SqlExplicitValuesStatement;
65
+ createExplicitValues<T extends object>(objectList: T[], columns?: ObjectToValueKeys<T>): SqlExplicitValuesStatement;
66
+ private _objectListToValues;
67
+ private _objectToValue;
57
68
  /**
58
69
  * @deprecated 请使用 objectToValue 代替
59
70
  */
60
71
  objectToValues<T extends object>(object: T, keys?: ObjectToValueKeys<T>): string;
61
72
  /**
73
+ * @deprecated 请使用 createImplicitValues 代替
62
74
  * 将对象转为 SQL 的 value
63
75
  * @example
64
76
  * ```ts
@@ -83,6 +95,7 @@ export declare class SqlValuesCreator {
83
95
  */
84
96
  toValues(values: readonly any[]): string;
85
97
  /**
98
+ * @deprecated 请使用 objectListToValues 代替
86
99
  * @public 创建 VALUES AS 语句
87
100
  * @example
88
101
  * ```ts
@@ -94,10 +107,20 @@ export declare class SqlValuesCreator {
94
107
  * // (VALUES (8:INT,'hhh':TEXT),(9,'row2')) AS customName(age, name)
95
108
  * ```
96
109
  */
97
- createValues<T extends {}>(asName: string, values: T[], valuesTypes: Record<string, string | {
110
+ createValues<T extends {}>(asName: string, values: T[], valuesTypes: Record<string, string | ({
98
111
  sqlType: string;
99
- sqlDefault?: string;
100
- assertJsType?: AssertJsType;
101
- }>): SqlStatementDataset<T>;
112
+ } & Pick<ColumnToValueConfig, "assertJsType" | "sqlDefault">)>): SqlStatementDataset<T>;
113
+ }
114
+ /** @public */
115
+ export type SqlValuesTextData = {
116
+ columns: string[];
117
+ text: string;
118
+ };
119
+ /** @public */
120
+ export declare class SqlExplicitValuesStatement {
121
+ columns: readonly string[];
122
+ readonly text: string;
123
+ constructor(columns: readonly string[], text: string);
124
+ toSelect(name: string): string;
102
125
  }
103
126
  //# sourceMappingURL=sql_value.d.ts.map
@@ -1,6 +1,6 @@
1
+ import { SqlTextStatementDataset } from '../SqlStatement.js';
1
2
  import { getObjectListKeys } from '../_statement.js';
2
3
  import { ValueSqlTemplate } from './ValueSqlTemplate.js';
3
- import { initColumnAssert, YourValuesAs } from './_utils.js';
4
4
 
5
5
  /**
6
6
  * SQL value 生成器
@@ -115,32 +115,56 @@ class SqlValuesCreator {
115
115
  defaultObject(value) {
116
116
  return SqlValuesCreator.string(JSON.stringify(value));
117
117
  }
118
- /** @deprecated 改用 objectListToValues */
119
- objectListToValuesList(objectList, keys, keepUndefinedKey) {
120
- return this.objectListToValues(objectList, keys, keepUndefinedKey).text;
118
+ /** @deprecated 改用 createImplicitValues */
119
+ objectListToValuesList(objectList, keys) {
120
+ return this.objectListToValues(objectList, keys).text;
121
121
  }
122
- objectListToValues(objectList, keys_types, keepUndefinedKey) {
122
+ /** @deprecated 请使用 objectListToValues 代替 */
123
+ objectListToValues(objectList, columns) {
124
+ return this.createImplicitValues(objectList, columns);
125
+ }
126
+ createImplicitValues(objectList, columns) {
127
+ let res;
128
+ if (objectList instanceof Array) {
129
+ res = this._objectListToValues(objectList, columns, { undefinedDefault: "DEFAULT" });
130
+ }
131
+ else {
132
+ res = this._objectToValue(objectList, columns, { undefinedDefault: "DEFAULT" });
133
+ }
134
+ return { columns: [...res.columns], text: res.text };
135
+ }
136
+ createExplicitValues(objectList, columns) {
137
+ if (objectList instanceof Array) {
138
+ return this._objectListToValues(objectList, columns, { undefinedDefault: "NULL" });
139
+ }
140
+ else {
141
+ return this._objectToValue(objectList, columns, { undefinedDefault: "NULL" });
142
+ }
143
+ }
144
+ _objectListToValues(objectList, columns, option = {}) {
123
145
  if (objectList.length <= 0)
124
146
  throw new Error("objectList 不能是空数组");
125
147
  let keys;
126
148
  let asserts;
127
- if (!keys_types) {
128
- keys = Array.from(getObjectListKeys(objectList, keepUndefinedKey));
149
+ if (!columns) {
150
+ keys = Array.from(getObjectListKeys(objectList));
129
151
  asserts = [];
130
152
  }
131
- else if (keys_types instanceof Array) {
132
- keys = keys_types;
153
+ else if (columns instanceof Array) {
154
+ keys = [...columns];
133
155
  asserts = [];
134
156
  }
135
157
  else {
136
- keys = Object.keys(keys_types);
137
- asserts = initColumnAssert(keys, keys_types);
158
+ keys = Object.keys(columns);
159
+ asserts = initColumnAssert(keys, columns);
138
160
  }
139
- let str = "(" + this._internalObjectToValues(objectList[0], keys, asserts) + ")";
161
+ const undefinedDefault = option.undefinedDefault || "DEFAULT";
162
+ let str = "(" + this._internalObjectToValues(objectList[0], keys, asserts, undefinedDefault) + ")";
140
163
  let i = 1;
141
164
  let j;
142
165
  let value;
143
166
  let rows;
167
+ let assert;
144
168
  try {
145
169
  for (; i < objectList.length; i++) {
146
170
  const object = objectList[i];
@@ -148,7 +172,9 @@ class SqlValuesCreator {
148
172
  j = 0;
149
173
  for (; j < keys.length; j++) {
150
174
  value = object[keys[j]];
151
- rows[j] = this.toSqlStr(value, asserts[j]?.assertJsType);
175
+ assert = asserts[j];
176
+ rows[j] =
177
+ value === undefined ? assert?.sqlDefault || undefinedDefault : this.toSqlStr(value, assert?.assertJsType);
152
178
  }
153
179
  str += ",\n(" + rows.join(",") + ")";
154
180
  }
@@ -157,16 +183,34 @@ class SqlValuesCreator {
157
183
  let message = error instanceof Error ? error.message : String(error);
158
184
  throw new Error("第 " + i + " 项,字段 '" + keys[j] + "' 异常," + message);
159
185
  }
160
- return { columns: keys, text: str };
186
+ return new SqlExplicitValuesStatement(keys, str);
161
187
  }
162
- objectToValues(object, keys_types) {
188
+ _objectToValue(object, keys_types, option = {}) {
163
189
  const { keys, type } = this._getObjectValueInfo(object, keys_types);
164
- return this._internalObjectToValues(object, keys, type);
190
+ const undefinedDefault = option.undefinedDefault || "DEFAULT";
191
+ const text = this._internalObjectToValues(object, keys, type, undefinedDefault);
192
+ return new SqlExplicitValuesStatement(keys, `(${text})`);
165
193
  }
166
- objectToValue(object, keys_types) {
194
+ objectToValues(object, keys_types) {
167
195
  const { keys, type } = this._getObjectValueInfo(object, keys_types);
168
- const text = this._internalObjectToValues(object, keys, type);
169
- return { columns: keys, text: "(" + text + ")" };
196
+ return this._internalObjectToValues(object, keys, type, "DEFAULT");
197
+ }
198
+ /**
199
+ * @deprecated 请使用 createImplicitValues 代替
200
+ * 将对象转为 SQL 的 value
201
+ * @example
202
+ * ```ts
203
+ * v.objectToValue({ a: 1, b: "2", c: null, d: undefined }).text // "('1', '2', NULL, DEFAULT)"
204
+ * v.objectToValue({ a: 1, b: "2", c: null, d: undefined }, ["a", "b"]).text // "('1', '2')"
205
+ * v.objectToValue(
206
+ * { a: 1, b: "2", c: null, d: undefined },
207
+ * { a: "INT", b: "TEXT", c: "JSONB", d: "TEXT" }
208
+ * ).text // "('1'::INT, '2'::TEXT, NULL::JSONB, DEFAULT::TEXT)"
209
+ * ```
210
+ * @param keys - 如果指定了key, object undefined 的属性值将填充为 null,如果不指定,将自获取 object 所有非 undefined 的属性的key
211
+ */
212
+ objectToValue(object, keys) {
213
+ return this.createImplicitValues(object, keys);
170
214
  }
171
215
  _getObjectValueInfo(object, keys_types) {
172
216
  let type;
@@ -185,7 +229,7 @@ class SqlValuesCreator {
185
229
  }
186
230
  return { keys, type };
187
231
  }
188
- _internalObjectToValues(object, keys, type) {
232
+ _internalObjectToValues(object, keys, type, undefinedDefault) {
189
233
  const values = [];
190
234
  let i = 0;
191
235
  let key;
@@ -197,12 +241,15 @@ class SqlValuesCreator {
197
241
  value = object[key];
198
242
  assertType = type[i];
199
243
  if (assertType) {
200
- values[i] = this.toSqlStr(value, assertType.assertJsType);
244
+ values[i] =
245
+ value === undefined
246
+ ? assertType.sqlDefault || undefinedDefault
247
+ : this.toSqlStr(value, assertType.assertJsType);
201
248
  if (assertType.sqlType)
202
249
  values[i] += "::" + assertType.sqlType;
203
250
  }
204
251
  else
205
- values[i] = this.toSqlStr(value);
252
+ values[i] = value === undefined ? undefinedDefault : this.toSqlStr(value);
206
253
  }
207
254
  }
208
255
  catch (error) {
@@ -228,51 +275,8 @@ class SqlValuesCreator {
228
275
  createValues(asName, values, valuesTypes) {
229
276
  if (values.length === 0)
230
277
  throw new Error("values 不能为空");
231
- const insertKeys = Object.keys(valuesTypes);
232
- const defaultValues = [];
233
- const asserts = new Array(insertKeys.length);
234
- const valuesStr = new Array(values.length);
235
- {
236
- const column0 = new Array(insertKeys.length);
237
- let columnName;
238
- let item;
239
- let sqlType;
240
- let assertJsType;
241
- let value;
242
- for (let i = 0; i < insertKeys.length; i++) {
243
- columnName = insertKeys[i];
244
- item = valuesTypes[columnName];
245
- if (typeof item === "string") {
246
- sqlType = item;
247
- defaultValues[i] = "NULL";
248
- }
249
- else {
250
- sqlType = item.sqlType;
251
- assertJsType = item.assertJsType;
252
- asserts[i] = assertJsType;
253
- defaultValues[i] = item.sqlDefault ?? "NULL";
254
- }
255
- value = values[0][columnName];
256
- if (value === undefined)
257
- column0[i] = defaultValues[i] + "::" + sqlType;
258
- else
259
- column0[i] = this.toSqlStr(value, assertJsType) + "::" + sqlType;
260
- }
261
- valuesStr[0] = "(" + column0.join(",") + ")";
262
- }
263
- let items = new Array(insertKeys.length);
264
- let value;
265
- for (let i = 1; i < values.length; i++) {
266
- for (let j = 0; j < insertKeys.length; j++) {
267
- value = values[i][insertKeys[j]];
268
- if (value === undefined)
269
- items[j] = defaultValues[j];
270
- else
271
- items[j] = this.toSqlStr(value, asserts[j]);
272
- }
273
- valuesStr[i] = "(" + items.join(",") + ")";
274
- }
275
- return new YourValuesAs(insertKeys, asName, valuesStr.join(",\n"));
278
+ const res = this.createExplicitValues(values, valuesTypes); // 预检数据
279
+ return new SqlTextStatementDataset(res.toSelect(asName));
276
280
  }
277
281
  }
278
282
  class AssertError extends TypeError {
@@ -280,5 +284,33 @@ class AssertError extends TypeError {
280
284
  super(`Assert ${assertType} type, Actual ${actual} type`);
281
285
  }
282
286
  }
287
+ function initColumnAssert(keys, keys_types) {
288
+ let key;
289
+ let value;
290
+ let type = new Array(keys.length);
291
+ for (let i = 0; i < keys.length; i++) {
292
+ key = keys[i];
293
+ value = keys_types[key];
294
+ if (typeof value === "string") {
295
+ type[i] = { sqlType: value };
296
+ }
297
+ else {
298
+ type[i] = value;
299
+ }
300
+ }
301
+ return type;
302
+ }
303
+ /** @public */
304
+ class SqlExplicitValuesStatement {
305
+ columns;
306
+ text;
307
+ constructor(columns, text) {
308
+ this.columns = columns;
309
+ this.text = text;
310
+ }
311
+ toSelect(name) {
312
+ return `(VALUES\n${this.text})\nAS ${name}(${this.columns.join(",")})`;
313
+ }
314
+ }
283
315
 
284
- export { SqlValuesCreator };
316
+ export { SqlExplicitValuesStatement, SqlValuesCreator };
@@ -1,19 +1,18 @@
1
1
  /** @public 断言类型 */
2
2
  export type AssertJsType = "bigint" | "number" | "string" | "boolean" | "object" | (new (...args: any[]) => any);
3
3
  /** @public */
4
- export type SqlValuesTextData = {
5
- columns: string[];
6
- text: string;
7
- };
8
- /** @public */
9
4
  export type ColumnToValueConfig = {
10
- /** 设置显式 SQL 类型,设置后会显示转换 SQL 值 */
5
+ /** 设置显式 SQL 类型,设置后会显式转换 SQL 值 */
11
6
  sqlType?: string;
12
7
  /** 设置 JS 转换器类型,引导转换器如何将 JS 值转换为 SQL 值 */
13
8
  assertJsType?: AssertJsType;
9
+ /** undefined 会被替换的值 */
10
+ sqlDefault?: string;
14
11
  };
15
12
  /** @public */
16
- export type ObjectToValueKeys<T extends {}> = readonly (keyof T)[] | {
17
- [key in keyof T]?: string | undefined | ColumnToValueConfig;
18
- };
13
+ export type ObjectToValueKeys<T extends {}> = readonly string[] | ({
14
+ [key in keyof T as key extends string ? key : never]?: string | ColumnToValueConfig;
15
+ } & {
16
+ [key: string]: string | undefined | ColumnToValueConfig;
17
+ });
19
18
  //# sourceMappingURL=type.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asla/yoursql",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "types": "./dist/mod.d.ts",
@@ -1,11 +0,0 @@
1
- import { SqlStatementDataset } from "../SqlStatement.ts";
2
- import { TableType } from "../util.ts";
3
- import { ColumnToValueConfig } from "./type.ts";
4
- export declare class YourValuesAs<T extends TableType> extends SqlStatementDataset<T> {
5
- #private;
6
- constructor(columns: readonly string[], asName: string, valuesStr: string);
7
- toSelect(): string;
8
- genSql(): string;
9
- }
10
- export declare function initColumnAssert(keys: readonly string[], keys_types: Record<string, string | undefined | ColumnToValueConfig>): any[];
11
- //# sourceMappingURL=_utils.d.ts.map
@@ -1,37 +0,0 @@
1
- import { SqlStatementDataset } from '../SqlStatement.js';
2
-
3
- class YourValuesAs extends SqlStatementDataset {
4
- constructor(columns, asName, valuesStr) {
5
- super();
6
- this.#asName = asName;
7
- this.#valuesStr = valuesStr;
8
- this.#sql = `(VALUES\n${this.#valuesStr})\nAS ${this.#asName}(${columns.join(",")})`;
9
- }
10
- #asName;
11
- #valuesStr;
12
- #sql;
13
- toSelect() {
14
- return this.#sql;
15
- }
16
- genSql() {
17
- return this.#sql;
18
- }
19
- }
20
- function initColumnAssert(keys, keys_types) {
21
- let key;
22
- let value;
23
- let type = new Array(keys.length);
24
- for (let i = 0; i < keys.length; i++) {
25
- key = keys[i];
26
- value = keys_types[key];
27
- if (typeof value === "string") {
28
- type[i] = { sqlType: value };
29
- }
30
- else {
31
- type[i] = value;
32
- }
33
- }
34
- return type;
35
- }
36
-
37
- export { YourValuesAs, initColumnAssert };