@asla/yoursql 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mod.d.ts +1 -0
- package/dist/mod.js +479 -316
- package/dist/select/TableQuery.d.ts +7 -12
- package/dist/select/_statement.d.ts +1 -10
- package/dist/select/select.d.ts +30 -41
- package/dist/select/selectable.d.ts +3 -2
- package/dist/select/type.d.ts +0 -7
- package/dist/sql_value/sql_value.d.ts +18 -1
- package/dist/util.d.ts +21 -0
- package/dist/your_table/checker.d.ts +13 -0
- package/dist/your_table/infer_db_type.d.ts +74 -0
- package/dist/your_table/mod.d.ts +4 -0
- package/dist/your_table/table.d.ts +16 -0
- package/package.json +2 -1
package/dist/mod.d.ts
CHANGED
package/dist/mod.js
CHANGED
|
@@ -54,8 +54,170 @@ function getObjectListKeys(objectList, keepUndefinedKey) {
|
|
|
54
54
|
}
|
|
55
55
|
return Array.from(keys);
|
|
56
56
|
}
|
|
57
|
+
/** @public */
|
|
58
|
+
function genWhere(where, type = "AND") {
|
|
59
|
+
return genWhereHaving(where, "WHERE", type);
|
|
60
|
+
}
|
|
61
|
+
/** @public */
|
|
62
|
+
function genHaving(having, type = "AND") {
|
|
63
|
+
return genWhereHaving(having, "HAVING", type);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @public
|
|
67
|
+
* ```ts
|
|
68
|
+
* genSelect({c1: true, c2: "count(*)", c3: "column"}) // "c1,count(*) AS c2,column as c3"
|
|
69
|
+
* genSelect(["c1", "count(*) AS c2", "column as c3"]) // "c1,count(*) AS c2,column as c3"
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
function genSelect(columns) {
|
|
73
|
+
let sql = "";
|
|
74
|
+
if (columns instanceof Array) {
|
|
75
|
+
if (columns.length)
|
|
76
|
+
sql += columns[0];
|
|
77
|
+
else
|
|
78
|
+
throw new Error("没有选择任何列");
|
|
79
|
+
for (let i = 1; i < columns.length; i++)
|
|
80
|
+
sql += "," + columns[i];
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const keys = Object.keys(columns);
|
|
84
|
+
if (keys.length === 0)
|
|
85
|
+
throw new Error("没有选择任何列");
|
|
86
|
+
let k = keys[0];
|
|
87
|
+
let v = columns[k];
|
|
88
|
+
if (typeof v === "string")
|
|
89
|
+
sql += v + " AS " + k;
|
|
90
|
+
else
|
|
91
|
+
sql += k;
|
|
92
|
+
for (let i = 1; i < keys.length; i++) {
|
|
93
|
+
k = keys[i];
|
|
94
|
+
v = columns[k];
|
|
95
|
+
sql += ",";
|
|
96
|
+
if (typeof v === "string")
|
|
97
|
+
sql += v + " AS " + k;
|
|
98
|
+
else
|
|
99
|
+
sql += k;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return sql;
|
|
103
|
+
}
|
|
104
|
+
/** @public */
|
|
105
|
+
function genOderBy(orderBy) {
|
|
106
|
+
if (typeof orderBy === "function")
|
|
107
|
+
orderBy = orderBy();
|
|
108
|
+
let sql = "";
|
|
109
|
+
if (typeof orderBy === "string")
|
|
110
|
+
sql += "\nORDER BY " + orderBy;
|
|
111
|
+
else if (orderBy instanceof Array) {
|
|
112
|
+
if (orderBy.length)
|
|
113
|
+
sql += "\nORDER BY " + orderBy.join(",");
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
let keys = Object.keys(orderBy);
|
|
117
|
+
if (keys.length)
|
|
118
|
+
sql += "\nORDER BY " + keys[0] + " " + orderBy[keys[0]];
|
|
119
|
+
for (let i = 1; i < keys.length; i++) {
|
|
120
|
+
sql += "," + orderBy[keys[i]] + " " + orderBy[keys[i]];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return sql;
|
|
124
|
+
}
|
|
125
|
+
function genWhereHaving(where, statement, type = "AND") {
|
|
126
|
+
if (typeof where === "function")
|
|
127
|
+
where = where();
|
|
128
|
+
type = " " + type + " ";
|
|
129
|
+
let sql = "";
|
|
130
|
+
if (typeof where === "string")
|
|
131
|
+
sql += "\n" + statement + " " + where;
|
|
132
|
+
else {
|
|
133
|
+
if (where.length)
|
|
134
|
+
sql += "\n" + statement + " " + +where[0];
|
|
135
|
+
for (let i = 1; i < where.length; i++)
|
|
136
|
+
sql += type + where[i];
|
|
137
|
+
}
|
|
138
|
+
return sql;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
var _SqlQueryStatement_sql;
|
|
142
|
+
/**
|
|
143
|
+
* 可选择项。可以是 table、查询结果等,它能被 select 语句选择
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* declare const item: SqlSelectable<any>
|
|
147
|
+
* await query(`select * from ${item.toSelect()}`)
|
|
148
|
+
*
|
|
149
|
+
* ```
|
|
150
|
+
* @public
|
|
151
|
+
*/
|
|
152
|
+
class SqlSelectable {
|
|
153
|
+
constructor(columns) {
|
|
154
|
+
// Reflect.set(this, SQL_SELECTABLE, undefined);
|
|
155
|
+
let readonlyColumns;
|
|
156
|
+
if (typeof columns[Symbol.iterator] === "function") {
|
|
157
|
+
let iterable = columns;
|
|
158
|
+
readonlyColumns = [];
|
|
159
|
+
let iter = iterable[Symbol.iterator]();
|
|
160
|
+
let i = 0;
|
|
161
|
+
let item = iter.next();
|
|
162
|
+
while (!item.done) {
|
|
163
|
+
readonlyColumns[i++] = item.value;
|
|
164
|
+
item = iter.next();
|
|
165
|
+
}
|
|
166
|
+
// readonlyColumns.length = i;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
let arrayLike = columns;
|
|
170
|
+
readonlyColumns = new Array(arrayLike.length);
|
|
171
|
+
// readonlyColumns.length = arrayLike.length;
|
|
172
|
+
for (let i = 0; i < arrayLike.length; i++) {
|
|
173
|
+
readonlyColumns[i] = arrayLike[i];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
this.columns = readonlyColumns;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* 数据库表
|
|
181
|
+
* @public
|
|
182
|
+
*/
|
|
183
|
+
class DbTable extends SqlSelectable {
|
|
184
|
+
constructor(name, columns) {
|
|
185
|
+
if (!(columns instanceof Array))
|
|
186
|
+
columns = Object.keys(columns);
|
|
187
|
+
super(columns);
|
|
188
|
+
this.name = name;
|
|
189
|
+
}
|
|
190
|
+
toSelect() {
|
|
191
|
+
return this.name;
|
|
192
|
+
}
|
|
193
|
+
toString() {
|
|
194
|
+
return this.name;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* SELECT 以及 UPDATE、DELETE、INSERT INTO 带结果的 SQL 语句
|
|
199
|
+
* @public
|
|
200
|
+
*/
|
|
201
|
+
class SqlQueryStatement extends SqlSelectable {
|
|
202
|
+
constructor(sql, columns) {
|
|
203
|
+
if (sql instanceof SqlQueryStatement) {
|
|
204
|
+
columns = sql.columns;
|
|
205
|
+
sql = __classPrivateFieldGet(sql, _SqlQueryStatement_sql, "f");
|
|
206
|
+
}
|
|
207
|
+
super(columns);
|
|
208
|
+
_SqlQueryStatement_sql.set(this, void 0);
|
|
209
|
+
__classPrivateFieldSet(this, _SqlQueryStatement_sql, sql, "f");
|
|
210
|
+
}
|
|
211
|
+
toString() {
|
|
212
|
+
return __classPrivateFieldGet(this, _SqlQueryStatement_sql, "f");
|
|
213
|
+
}
|
|
214
|
+
toSelect() {
|
|
215
|
+
return "(" + this.toString() + ")";
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
_SqlQueryStatement_sql = new WeakMap();
|
|
57
219
|
|
|
58
|
-
var _SqlRaw_value;
|
|
220
|
+
var _SqlRaw_value, _YourValuesAs_asName, _YourValuesAs_valuesStr, _YourValuesAs_sql;
|
|
59
221
|
/**
|
|
60
222
|
* SQL 原始字符对象
|
|
61
223
|
* @public
|
|
@@ -217,7 +379,70 @@ class SqlValuesCreator {
|
|
|
217
379
|
toValues(values) {
|
|
218
380
|
return values.map((v) => this.toSqlStr(v)).join(",");
|
|
219
381
|
}
|
|
382
|
+
createValues(asName, values, valuesTypes) {
|
|
383
|
+
if (values.length === 0)
|
|
384
|
+
throw new Error("values 不能为空");
|
|
385
|
+
const insertKeys = Object.keys(valuesTypes);
|
|
386
|
+
const defaultValues = [];
|
|
387
|
+
const valuesStr = new Array(values.length);
|
|
388
|
+
{
|
|
389
|
+
const column0 = new Array(insertKeys.length);
|
|
390
|
+
let columnName;
|
|
391
|
+
let item;
|
|
392
|
+
let type;
|
|
393
|
+
let value;
|
|
394
|
+
for (let i = 0; i < insertKeys.length; i++) {
|
|
395
|
+
columnName = insertKeys[i];
|
|
396
|
+
item = valuesTypes[columnName];
|
|
397
|
+
if (typeof item === "string") {
|
|
398
|
+
type = item;
|
|
399
|
+
defaultValues[i] = "NULL";
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
type = item.sqlType;
|
|
403
|
+
defaultValues[i] = item.sqlDefault ?? "NULL";
|
|
404
|
+
}
|
|
405
|
+
value = values[0][columnName];
|
|
406
|
+
if (value === undefined)
|
|
407
|
+
column0[i] = defaultValues[i] + "::" + type;
|
|
408
|
+
else
|
|
409
|
+
column0[i] = this.toSqlStr(value) + "::" + type;
|
|
410
|
+
}
|
|
411
|
+
valuesStr[0] = "(" + column0.join(",") + ")";
|
|
412
|
+
}
|
|
413
|
+
let items = new Array(insertKeys.length);
|
|
414
|
+
let value;
|
|
415
|
+
for (let i = 1; i < values.length; i++) {
|
|
416
|
+
for (let j = 0; j < insertKeys.length; j++) {
|
|
417
|
+
value = values[i][insertKeys[j]];
|
|
418
|
+
if (value === undefined)
|
|
419
|
+
items[j] = defaultValues[j];
|
|
420
|
+
else
|
|
421
|
+
items[j] = this.toSqlStr(value);
|
|
422
|
+
}
|
|
423
|
+
valuesStr[i] = "(" + items.join(",") + ")";
|
|
424
|
+
}
|
|
425
|
+
return new YourValuesAs(insertKeys, asName, valuesStr.join(",\n"));
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
class YourValuesAs extends SqlSelectable {
|
|
429
|
+
constructor(columns, asName, valuesStr) {
|
|
430
|
+
super(columns);
|
|
431
|
+
_YourValuesAs_asName.set(this, void 0);
|
|
432
|
+
_YourValuesAs_valuesStr.set(this, void 0);
|
|
433
|
+
_YourValuesAs_sql.set(this, void 0);
|
|
434
|
+
__classPrivateFieldSet(this, _YourValuesAs_asName, asName, "f");
|
|
435
|
+
__classPrivateFieldSet(this, _YourValuesAs_valuesStr, valuesStr, "f");
|
|
436
|
+
__classPrivateFieldSet(this, _YourValuesAs_sql, `(VALUES\n${__classPrivateFieldGet(this, _YourValuesAs_valuesStr, "f")})\nAS ${__classPrivateFieldGet(this, _YourValuesAs_asName, "f")}(${this.columns.join(",")})`, "f");
|
|
437
|
+
}
|
|
438
|
+
toSelect() {
|
|
439
|
+
return __classPrivateFieldGet(this, _YourValuesAs_sql, "f");
|
|
440
|
+
}
|
|
441
|
+
toString() {
|
|
442
|
+
return __classPrivateFieldGet(this, _YourValuesAs_sql, "f");
|
|
443
|
+
}
|
|
220
444
|
}
|
|
445
|
+
_YourValuesAs_asName = new WeakMap(), _YourValuesAs_valuesStr = new WeakMap(), _YourValuesAs_sql = new WeakMap();
|
|
221
446
|
function toKeyType(object, keys_types) {
|
|
222
447
|
let type = {};
|
|
223
448
|
let keys;
|
|
@@ -259,107 +484,98 @@ const pgSqlTransformer = new Map([
|
|
|
259
484
|
[Date, (value) => SqlValuesCreator.string(value.toISOString())],
|
|
260
485
|
]);
|
|
261
486
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
* declare const item: SqlSelectable<any>
|
|
267
|
-
* await query(`select * from ${item.toSelect()}`)
|
|
268
|
-
*
|
|
269
|
-
* ```
|
|
270
|
-
* @public
|
|
271
|
-
*/
|
|
272
|
-
class SqlSelectable {
|
|
273
|
-
constructor(columns) {
|
|
274
|
-
// Reflect.set(this, SQL_SELECTABLE, undefined);
|
|
275
|
-
let readonlyColumns;
|
|
276
|
-
if (typeof columns[Symbol.iterator] === "function") {
|
|
277
|
-
let iterable = columns;
|
|
278
|
-
readonlyColumns = [];
|
|
279
|
-
let iter = iterable[Symbol.iterator]();
|
|
280
|
-
let i = 0;
|
|
281
|
-
let item = iter.next();
|
|
282
|
-
while (!item.done) {
|
|
283
|
-
readonlyColumns[i++] = item.value;
|
|
284
|
-
item = iter.next();
|
|
285
|
-
}
|
|
286
|
-
// readonlyColumns.length = i;
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
let arrayLike = columns;
|
|
290
|
-
readonlyColumns = new Array(arrayLike.length);
|
|
291
|
-
// readonlyColumns.length = arrayLike.length;
|
|
292
|
-
for (let i = 0; i < arrayLike.length; i++) {
|
|
293
|
-
readonlyColumns[i] = arrayLike[i];
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
this.columns = readonlyColumns;
|
|
487
|
+
var _SelectImpl_instances, _a, _SelectImpl_join;
|
|
488
|
+
class FinalSelectImpl extends SqlQueryStatement {
|
|
489
|
+
constructor(statement) {
|
|
490
|
+
super(statement);
|
|
297
491
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if (
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
this.name = name;
|
|
492
|
+
filter(option) {
|
|
493
|
+
let { orderBy } = option;
|
|
494
|
+
let sql = this.toString();
|
|
495
|
+
if (orderBy)
|
|
496
|
+
sql += genOderBy(orderBy);
|
|
497
|
+
if (option.limit)
|
|
498
|
+
sql += "\nLIMIT " + option.limit;
|
|
499
|
+
if (option.offset)
|
|
500
|
+
sql += "\nOFFSET " + option.offset;
|
|
501
|
+
return new SqlQueryStatement(sql, Array.from(this.columns));
|
|
309
502
|
}
|
|
310
|
-
|
|
311
|
-
|
|
503
|
+
}
|
|
504
|
+
/** @public */
|
|
505
|
+
function createSelect(selectable, as) {
|
|
506
|
+
return new SelectImpl("FROM " + fromAs(selectable, as));
|
|
507
|
+
}
|
|
508
|
+
function fromAs(selectable, as) {
|
|
509
|
+
let sql = typeof selectable === "string" ? selectable : selectable.toSelect();
|
|
510
|
+
if (as)
|
|
511
|
+
sql += " AS " + as;
|
|
512
|
+
return sql;
|
|
513
|
+
}
|
|
514
|
+
class SelectImpl {
|
|
515
|
+
constructor(str) {
|
|
516
|
+
_SelectImpl_instances.add(this);
|
|
517
|
+
this.str = str;
|
|
312
518
|
}
|
|
313
519
|
toString() {
|
|
314
|
-
return this.
|
|
520
|
+
return this.str;
|
|
315
521
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
* SELECT 以及 UPDATE、DELETE、INSERT INTO 带结果的 SQL 语句
|
|
319
|
-
* @public
|
|
320
|
-
*/
|
|
321
|
-
class SqlQueryStatement extends SqlSelectable {
|
|
322
|
-
constructor(sql, columns) {
|
|
323
|
-
super(columns);
|
|
324
|
-
this.sql = sql;
|
|
522
|
+
fullJoin(selectable, as, on) {
|
|
523
|
+
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_join).call(this, "FULL JOIN", selectable, as, on);
|
|
325
524
|
}
|
|
326
|
-
|
|
327
|
-
return this.
|
|
525
|
+
innerJoin(selectable, as, on) {
|
|
526
|
+
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_join).call(this, "INNER JOIN", selectable, as, on);
|
|
328
527
|
}
|
|
329
|
-
|
|
330
|
-
return
|
|
528
|
+
leftJoin(selectable, as, on) {
|
|
529
|
+
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_join).call(this, "LEFT JOIN", selectable, as, on);
|
|
331
530
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
function genOderBy(orderBy, orderNullRule) {
|
|
335
|
-
let select = [];
|
|
336
|
-
let v;
|
|
337
|
-
for (const key of Object.keys(orderBy)) {
|
|
338
|
-
v = orderBy[key];
|
|
339
|
-
switch (v) {
|
|
340
|
-
case "ASC":
|
|
341
|
-
break;
|
|
342
|
-
case "DESC":
|
|
343
|
-
break;
|
|
344
|
-
default:
|
|
345
|
-
throw new Error("orderBy 只能是 ASE 或 DESC. 当前值:" + String(v));
|
|
346
|
-
}
|
|
347
|
-
select.push(key + " " + v);
|
|
531
|
+
rightJoin(selectable, as, on) {
|
|
532
|
+
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_join).call(this, "RIGHT JOIN", selectable, as, on);
|
|
348
533
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
534
|
+
naturalJoin(selectable, as) {
|
|
535
|
+
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_join).call(this, "NATURAL JOIN", selectable, as);
|
|
536
|
+
}
|
|
537
|
+
crossJoin(selectable, as) {
|
|
538
|
+
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_join).call(this, "CROSS JOIN", selectable, as);
|
|
539
|
+
}
|
|
540
|
+
from(selectable, as) {
|
|
541
|
+
return new _a(this.str + "," + fromAs(selectable, as));
|
|
542
|
+
}
|
|
543
|
+
select(columnsIn) {
|
|
544
|
+
let sql = "SELECT ";
|
|
545
|
+
let columns = [];
|
|
546
|
+
if (typeof columnsIn === "string")
|
|
547
|
+
sql += columnsIn;
|
|
548
|
+
else {
|
|
549
|
+
sql += genSelect(columnsIn);
|
|
550
|
+
if (columnsIn instanceof Array) ;
|
|
551
|
+
else
|
|
552
|
+
columns = Object.keys(columnsIn);
|
|
358
553
|
}
|
|
359
|
-
sql += "
|
|
554
|
+
sql += "\n" + this.str;
|
|
555
|
+
return new FinalSelectImpl(new SqlQueryStatement(sql, columns));
|
|
556
|
+
}
|
|
557
|
+
groupBy(columns) {
|
|
558
|
+
let sql = this.str;
|
|
559
|
+
if (typeof columns === "string")
|
|
560
|
+
sql += " GROUP BY " + columns;
|
|
561
|
+
else
|
|
562
|
+
sql += " GROUP BY " + columns.join(",");
|
|
563
|
+
return new _a(sql);
|
|
564
|
+
}
|
|
565
|
+
having(param) {
|
|
566
|
+
return new _a(this.str + genWhere(param));
|
|
567
|
+
}
|
|
568
|
+
where(param) {
|
|
569
|
+
return new _a(this.str + genWhere(param));
|
|
360
570
|
}
|
|
361
|
-
return sql;
|
|
362
571
|
}
|
|
572
|
+
_a = SelectImpl, _SelectImpl_instances = new WeakSet(), _SelectImpl_join = function _SelectImpl_join(type, selectable, as, on) {
|
|
573
|
+
let sql = this.str + "\n" + type + " " + fromAs(selectable, as);
|
|
574
|
+
if (on)
|
|
575
|
+
sql += " ON " + on;
|
|
576
|
+
return new _a(sql);
|
|
577
|
+
};
|
|
578
|
+
|
|
363
579
|
function selectColumnsOrTable(columns) {
|
|
364
580
|
let sqlSelect;
|
|
365
581
|
let select;
|
|
@@ -387,236 +603,15 @@ function selectColumnsOrTable(columns) {
|
|
|
387
603
|
throw new Error("选择列为空");
|
|
388
604
|
return { columns: select, sqlColumns: sqlSelect.join(", ") };
|
|
389
605
|
}
|
|
390
|
-
/**
|
|
391
|
-
* @param select 选择的行
|
|
392
|
-
* @param tableColumns 全部行
|
|
393
|
-
* @param push 要讲选择的行加入到集合中。
|
|
394
|
-
*/
|
|
395
|
-
function genNewColumns(select, tableColumns,
|
|
396
|
-
/** newName -> oldName */
|
|
397
|
-
push = new Map()) {
|
|
398
|
-
if (select === "*") {
|
|
399
|
-
for (const key of tableColumns) {
|
|
400
|
-
if (push.has(key))
|
|
401
|
-
throw new ColumnRepeatError(key);
|
|
402
|
-
push.set(key, null);
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
else {
|
|
406
|
-
genSelectAsColumns(select, push);
|
|
407
|
-
}
|
|
408
|
-
return push;
|
|
409
|
-
}
|
|
410
|
-
function genSelectAsColumns(select,
|
|
411
|
-
/** newName -> oldName */
|
|
412
|
-
push = new Map()) {
|
|
413
|
-
if (select instanceof Array) {
|
|
414
|
-
for (const key of select) {
|
|
415
|
-
if (push.has(key))
|
|
416
|
-
throw new ColumnRepeatError(key);
|
|
417
|
-
push.set(key, null);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
let finalName;
|
|
422
|
-
for (const oldName of Object.keys(select)) {
|
|
423
|
-
if (typeof select[oldName] === "string")
|
|
424
|
-
finalName = select[oldName];
|
|
425
|
-
else if (select[oldName])
|
|
426
|
-
finalName = oldName;
|
|
427
|
-
else
|
|
428
|
-
continue;
|
|
429
|
-
if (push.has(finalName))
|
|
430
|
-
throw new ColumnRepeatError(finalName);
|
|
431
|
-
push.set(finalName, oldName);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
return push;
|
|
435
|
-
}
|
|
436
|
-
class ColumnRepeatError extends Error {
|
|
437
|
-
constructor(columnName) {
|
|
438
|
-
super("Column name '" + columnName + "' repeated");
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
var _SelectImpl_instances, _a, _SelectImpl_joinOn, _SelectImpl_join;
|
|
443
|
-
/** @public */
|
|
444
|
-
const createSelect = function createSelect(tb, columns, option) {
|
|
445
|
-
let select = createSelectMap(tb, columns, option).selects;
|
|
446
|
-
return new SelectImpl(select);
|
|
447
|
-
};
|
|
448
|
-
function* mergeColumns(a, b) {
|
|
449
|
-
for (const { columns } of a)
|
|
450
|
-
yield* columns.keys();
|
|
451
|
-
yield* b;
|
|
452
|
-
}
|
|
453
|
-
class SelectImpl extends SqlSelectable {
|
|
454
|
-
constructor(tableList, addedColumns) {
|
|
455
|
-
super(addedColumns ? mergeColumns(tableList.values(), addedColumns.keys()) : tableList.keys());
|
|
456
|
-
_SelectImpl_instances.add(this);
|
|
457
|
-
this.tableList = tableList;
|
|
458
|
-
this.addedColumns = addedColumns;
|
|
459
|
-
}
|
|
460
|
-
toSelect() {
|
|
461
|
-
return "(" + this.toString() + ")";
|
|
462
|
-
}
|
|
463
|
-
toString() {
|
|
464
|
-
let tables = [];
|
|
465
|
-
let join = "";
|
|
466
|
-
let selectColumns = [];
|
|
467
|
-
const size = this.tableList.size;
|
|
468
|
-
for (const [tableAs, { columns, from, on, type }] of this.tableList) {
|
|
469
|
-
let tableStr = tableAs === from ? from : from + " AS " + tableAs;
|
|
470
|
-
if (type) {
|
|
471
|
-
join += "\n" + type + " " + tableStr;
|
|
472
|
-
if (on)
|
|
473
|
-
join += " ON " + on;
|
|
474
|
-
}
|
|
475
|
-
else {
|
|
476
|
-
tables.push(tableStr);
|
|
477
|
-
}
|
|
478
|
-
if (size === 1 && tableAs === from) {
|
|
479
|
-
for (const [column, oldName] of columns) {
|
|
480
|
-
if (!oldName || oldName == column)
|
|
481
|
-
selectColumns.push(column);
|
|
482
|
-
else
|
|
483
|
-
selectColumns.push(oldName + " AS " + column);
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
else {
|
|
487
|
-
for (const [column, oldName] of columns) {
|
|
488
|
-
if (!oldName || oldName === column)
|
|
489
|
-
selectColumns.push(tableAs + "." + column);
|
|
490
|
-
else
|
|
491
|
-
selectColumns.push(tableAs + "." + oldName + " AS " + column);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
if (this.addedColumns) {
|
|
496
|
-
for (const [asName, columnStr] of this.addedColumns) {
|
|
497
|
-
if (asName === columnStr)
|
|
498
|
-
selectColumns.push(asName);
|
|
499
|
-
else
|
|
500
|
-
selectColumns.push(columnStr + " AS " + asName);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
if (selectColumns.length === 0)
|
|
504
|
-
throw new Error("Columns 为空");
|
|
505
|
-
let sql = `SELECT ${selectColumns.join(", ")}\nFROM ${tables.join(", ")}` + join;
|
|
506
|
-
return sql;
|
|
507
|
-
}
|
|
508
|
-
fullJoin(tb, columns, option) {
|
|
509
|
-
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_joinOn).call(this, "FULL JOIN", tb, columns, option);
|
|
510
|
-
}
|
|
511
|
-
innerJoin(tb, columns, option) {
|
|
512
|
-
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_joinOn).call(this, "INNER JOIN", tb, columns, option);
|
|
513
|
-
}
|
|
514
|
-
leftJoin(tb, columns, option) {
|
|
515
|
-
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_joinOn).call(this, "LEFT JOIN", tb, columns, option);
|
|
516
|
-
}
|
|
517
|
-
rightJoin(tb, columns, option) {
|
|
518
|
-
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_joinOn).call(this, "RIGHT JOIN", tb, columns, option);
|
|
519
|
-
}
|
|
520
|
-
naturalJoin(tb, columns, option) {
|
|
521
|
-
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_join).call(this, "NATURAL JOIN", tb, columns, option);
|
|
522
|
-
}
|
|
523
|
-
crossJoin(tb, columns, option) {
|
|
524
|
-
return __classPrivateFieldGet(this, _SelectImpl_instances, "m", _SelectImpl_join).call(this, "CROSS JOIN", tb, columns, option);
|
|
525
|
-
}
|
|
526
|
-
select(tb, columns, option) {
|
|
527
|
-
let select = createSelectMap(tb, columns, option, this.tableList).selects;
|
|
528
|
-
const obj = new _a(select, new Map(this.addedColumns));
|
|
529
|
-
return obj;
|
|
530
|
-
}
|
|
531
|
-
addColumns(add) {
|
|
532
|
-
let addedColumns = this.addedColumns ? new Map(this.addedColumns) : new Map();
|
|
533
|
-
for (const [asNewName, columnStr] of Object.entries(add)) {
|
|
534
|
-
if (addedColumns.has(asNewName))
|
|
535
|
-
throw new Error(`The column ${asNewName} already exists`);
|
|
536
|
-
addedColumns.set(asNewName, columnStr);
|
|
537
|
-
}
|
|
538
|
-
return new _a(this.tableList, addedColumns);
|
|
539
|
-
}
|
|
540
|
-
toQuery(option = {}) {
|
|
541
|
-
const { where, orderNullRule } = option;
|
|
542
|
-
let sql = this.toString();
|
|
543
|
-
if (where)
|
|
544
|
-
sql += "\nWHERE " + where;
|
|
545
|
-
const orderBy = option.orderBy;
|
|
546
|
-
if (orderBy)
|
|
547
|
-
sql += genOderBy(orderBy, orderNullRule);
|
|
548
|
-
if (option.limit)
|
|
549
|
-
sql += "\nLIMIT " + option.limit;
|
|
550
|
-
if (option.offset)
|
|
551
|
-
sql += "\nOFFSET " + option.offset;
|
|
552
|
-
return new SqlQueryStatement(sql, Array.from(this.columns));
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
_a = SelectImpl, _SelectImpl_instances = new WeakSet(), _SelectImpl_joinOn = function _SelectImpl_joinOn(type, tb, columns, option) {
|
|
556
|
-
let { selects, tbInfo } = createSelectMap(tb, columns, option, this.tableList);
|
|
557
|
-
tbInfo.type = type;
|
|
558
|
-
tbInfo.on = option.on;
|
|
559
|
-
const next = new _a(selects, new Map(this.addedColumns));
|
|
560
|
-
Object.defineProperty(next, "select", { value: undefined, configurable: false, enumerable: false });
|
|
561
|
-
return next;
|
|
562
|
-
}, _SelectImpl_join = function _SelectImpl_join(type, tb, columns, option) {
|
|
563
|
-
let { selects, tbInfo } = createSelectMap(tb, columns, option, this.tableList);
|
|
564
|
-
tbInfo.type = type;
|
|
565
|
-
const next = new _a(selects, new Map(this.addedColumns));
|
|
566
|
-
Object.defineProperty(next, "select", { value: undefined, configurable: false, enumerable: false });
|
|
567
|
-
return next;
|
|
568
|
-
};
|
|
569
|
-
function createSelectMap(tb, columns, option = {}, selects) {
|
|
570
|
-
let select = new Map(selects);
|
|
571
|
-
let tableAs;
|
|
572
|
-
let tbInfo;
|
|
573
|
-
if (typeof tb === "string") {
|
|
574
|
-
throw new Error("tb 应是 SqlSelectable 类型");
|
|
575
|
-
// if (typeof columns !== "object") throw new Error("缺少 option.columns");
|
|
576
|
-
// const newColumns = genSelectAsColumns(columns);
|
|
577
|
-
// tableAs = option.tableAs ?? tb;
|
|
578
|
-
// tbInfo = { table: tb, columns: newColumns };
|
|
579
|
-
}
|
|
580
|
-
else {
|
|
581
|
-
const from = tb.toSelect();
|
|
582
|
-
if (tb instanceof DbTable) {
|
|
583
|
-
tableAs = option.tableAs ?? from;
|
|
584
|
-
}
|
|
585
|
-
else {
|
|
586
|
-
tableAs = option.tableAs ?? "t" + select.size;
|
|
587
|
-
}
|
|
588
|
-
if (columns) {
|
|
589
|
-
const newColumns = genNewColumns(columns, tb.columns);
|
|
590
|
-
tbInfo = { from, columns: newColumns };
|
|
591
|
-
}
|
|
592
|
-
else
|
|
593
|
-
tbInfo = { from, columns: new Map() };
|
|
594
|
-
}
|
|
595
|
-
if (select.has(tableAs))
|
|
596
|
-
throw new TableRepeatError(tableAs);
|
|
597
|
-
select.set(tableAs, tbInfo);
|
|
598
|
-
return { selects: select, tbInfo: tbInfo };
|
|
599
|
-
}
|
|
600
|
-
class TableRepeatError extends Error {
|
|
601
|
-
constructor(tableName) {
|
|
602
|
-
super("Table name '" + tableName + "' repeated");
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
// interface SqlFrom<T extends object> {
|
|
606
|
-
// from<A extends object>(table: SqlSelectable<A>): SqlFrom<T & A>;
|
|
607
|
-
// }
|
|
608
|
-
// declare function from<T extends SqlSelectable<any>[]>(...table: T): Select<MergeSelectable<T>>;
|
|
609
|
-
// type MergeSelectable<T extends any[]> = T extends [SqlSelectable<infer P>, ...infer Q] ? P & MergeSelectable<Q> : {};
|
|
610
606
|
|
|
611
607
|
/** @public */
|
|
612
608
|
class DbTableQuery extends DbTable {
|
|
613
609
|
constructor(name, columns, statement) {
|
|
614
610
|
super(name, columns);
|
|
615
|
-
this.name = name;
|
|
616
611
|
this.statement = statement;
|
|
617
612
|
}
|
|
618
|
-
|
|
619
|
-
return createSelect(this,
|
|
613
|
+
fromAs(as) {
|
|
614
|
+
return createSelect(this, as);
|
|
620
615
|
}
|
|
621
616
|
insert(values, option) {
|
|
622
617
|
let insertCol;
|
|
@@ -703,8 +698,176 @@ function genRetuningSql(sql, returns, tableColumns) {
|
|
|
703
698
|
sql += "\nRETURNING " + columnsStr;
|
|
704
699
|
return new SqlQueryStatement(sql, columns);
|
|
705
700
|
}
|
|
706
|
-
|
|
707
|
-
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* 表格列的信息
|
|
704
|
+
* @public
|
|
705
|
+
*/
|
|
706
|
+
class ColumnMeta {
|
|
707
|
+
constructor(type,
|
|
708
|
+
/** 数据库原始数据类型 */
|
|
709
|
+
sqlType,
|
|
710
|
+
/** 是否非空 */
|
|
711
|
+
notNull = false,
|
|
712
|
+
/** 是否是数组类型 */
|
|
713
|
+
isArray = false,
|
|
714
|
+
/** 数据库原始默认值 */
|
|
715
|
+
sqlDefault) {
|
|
716
|
+
this.type = type;
|
|
717
|
+
this.sqlType = sqlType;
|
|
718
|
+
this.notNull = notNull;
|
|
719
|
+
this.isArray = isArray;
|
|
720
|
+
this.sqlDefault = sqlDefault;
|
|
721
|
+
}
|
|
722
|
+
/** 校验 value 的类型 */
|
|
723
|
+
checkValue(value) {
|
|
724
|
+
if (typeof this.type === "function")
|
|
725
|
+
return value instanceof this.type;
|
|
726
|
+
return this.type.is(value);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* 数据库类型到JS类型的映射
|
|
731
|
+
* @public
|
|
732
|
+
*/
|
|
733
|
+
class YourTypeMap {
|
|
734
|
+
static create(rawTypeMap) {
|
|
735
|
+
return new this(rawTypeMap);
|
|
736
|
+
}
|
|
737
|
+
constructor(typeMap = {}) {
|
|
738
|
+
this.typeMap = typeMap;
|
|
739
|
+
}
|
|
740
|
+
genColumn(type, notNull, defaultValue) {
|
|
741
|
+
const constructor = Reflect.get(this.typeMap, type);
|
|
742
|
+
const column = new ColumnMeta(constructor, type, notNull, false, defaultValue);
|
|
743
|
+
return column;
|
|
744
|
+
}
|
|
745
|
+
genArrColumn(type, notNull, defaultValue) {
|
|
746
|
+
const constructor = Reflect.get(this.typeMap, type);
|
|
747
|
+
const column = new ColumnMeta(constructor, type + "[]", notNull, true, defaultValue);
|
|
748
|
+
return column;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
function baseType(v) {
|
|
752
|
+
return typeof v === this.name;
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* 自定义数据类型
|
|
756
|
+
* @public
|
|
757
|
+
*/
|
|
758
|
+
class CustomDbType {
|
|
759
|
+
constructor(is, name) {
|
|
760
|
+
this.is = is;
|
|
761
|
+
this.name = name;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
CustomDbType.bigint = new CustomDbType(baseType, "bigint");
|
|
765
|
+
CustomDbType.number = new CustomDbType(baseType, "number");
|
|
766
|
+
CustomDbType.string = new CustomDbType(baseType, "string");
|
|
767
|
+
CustomDbType.boolean = new CustomDbType(baseType, "boolean");
|
|
768
|
+
|
|
769
|
+
/** @public */
|
|
770
|
+
class TypeChecker {
|
|
771
|
+
constructor(map) {
|
|
772
|
+
this.map = map;
|
|
773
|
+
}
|
|
774
|
+
check(value) {
|
|
775
|
+
const map = this.map;
|
|
776
|
+
let v;
|
|
777
|
+
for (const [k, expect] of map) {
|
|
778
|
+
v = value[k];
|
|
779
|
+
let err;
|
|
780
|
+
if (v === null) {
|
|
781
|
+
if (expect.notNull)
|
|
782
|
+
throw new Error(`${k} 不能为空`);
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
else if (v === undefined) {
|
|
786
|
+
if (expect.sqlDefault === undefined && expect.notNull)
|
|
787
|
+
throw new Error(`${k} 不能为 undefined`);
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
else if (expect.isArray) {
|
|
791
|
+
if (v instanceof Array)
|
|
792
|
+
err = this.checkArray(v, expect.type);
|
|
793
|
+
else
|
|
794
|
+
err = getErrStr(`Array<${expect.type.name}>`, typeof v);
|
|
795
|
+
}
|
|
796
|
+
else {
|
|
797
|
+
err = this.checkItem(v, expect.type);
|
|
798
|
+
}
|
|
799
|
+
if (err)
|
|
800
|
+
throw new Error(`Key ${k} error: ${err}`);
|
|
801
|
+
}
|
|
802
|
+
return value;
|
|
803
|
+
}
|
|
804
|
+
checkList(value) {
|
|
805
|
+
let i = 0;
|
|
806
|
+
try {
|
|
807
|
+
for (let i = 0; i < value.length; i++) {
|
|
808
|
+
this.check(value[i]);
|
|
809
|
+
}
|
|
810
|
+
return value;
|
|
811
|
+
}
|
|
812
|
+
catch (error) {
|
|
813
|
+
throw new Error(`Item ${i}, ${error.message}`);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
checkArray(v, expect) {
|
|
817
|
+
let err;
|
|
818
|
+
for (let i = 0; i < v.length; i++) {
|
|
819
|
+
err = this.checkItem(v[i], expect);
|
|
820
|
+
if (err)
|
|
821
|
+
return `Item[${i}] ${err}`;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
checkItem(v, expect) {
|
|
825
|
+
if (expect instanceof CustomDbType) {
|
|
826
|
+
if (expect.is(v))
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
else {
|
|
830
|
+
if (v instanceof expect)
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
let actName = typeof v;
|
|
834
|
+
if (actName === "object") {
|
|
835
|
+
if (v === null)
|
|
836
|
+
actName = "null";
|
|
837
|
+
else
|
|
838
|
+
actName = v.constructor?.name ?? "object";
|
|
839
|
+
}
|
|
840
|
+
return getErrStr(expect.name, typeof v);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
function getErrStr(expect, actual) {
|
|
844
|
+
return `Expect ${expect}, Actual ${actual}`;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
* 完整数据库表数据
|
|
849
|
+
* @public
|
|
850
|
+
*/
|
|
851
|
+
class YourTable extends DbTableQuery {
|
|
852
|
+
constructor(name, define, sqlValue) {
|
|
853
|
+
super(name, Object.keys(define), sqlValue);
|
|
854
|
+
this.define = define;
|
|
855
|
+
}
|
|
856
|
+
getColumnMeta(name) {
|
|
857
|
+
return Reflect.get(this.define, name);
|
|
858
|
+
}
|
|
859
|
+
createTypeChecker(keys) {
|
|
860
|
+
let map = new Map();
|
|
861
|
+
let defined = this.define;
|
|
862
|
+
let k;
|
|
863
|
+
for (let i = 0; i < keys.length; i++) {
|
|
864
|
+
k = keys[i];
|
|
865
|
+
if (defined[k] === undefined)
|
|
866
|
+
throw new Error(`key ${k} 未定义`);
|
|
867
|
+
map.set(k, defined[k]);
|
|
868
|
+
}
|
|
869
|
+
return new TypeChecker(map);
|
|
870
|
+
}
|
|
708
871
|
}
|
|
709
872
|
|
|
710
|
-
export { DbTable, DbTableQuery, SqlQueryStatement, SqlRaw, SqlSelectable, SqlValuesCreator, createSelect, getObjectListKeys, pgSqlTransformer };
|
|
873
|
+
export { ColumnMeta, CustomDbType, DbTable, DbTableQuery, SqlQueryStatement, SqlRaw, SqlSelectable, SqlValuesCreator, TypeChecker, YourTable, YourTypeMap, createSelect, genHaving, genOderBy, genSelect, genWhere, getObjectListKeys, pgSqlTransformer };
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import { SqlValuesCreator, SqlRaw } from "../sql_value/sql_value.ts";
|
|
2
|
-
import { ColumnsSelected,
|
|
3
|
-
import {
|
|
2
|
+
import { ColumnsSelected, SelectColumns, UpdateRowValue, TableType } from "./type.ts";
|
|
3
|
+
import { JoinSelect } from "./select.ts";
|
|
4
4
|
import { DbTable, SqlQueryStatement } from "./selectable.ts";
|
|
5
|
+
import { WhereParam } from "../util.ts";
|
|
5
6
|
/** @public */
|
|
6
7
|
export declare class DbTableQuery<T extends TableType = Record<string, any>, C extends TableType = Partial<T>> extends DbTable<T> {
|
|
7
|
-
readonly name: string;
|
|
8
8
|
private statement;
|
|
9
9
|
constructor(name: string, columns: readonly string[], statement: SqlValuesCreator);
|
|
10
|
-
|
|
11
|
-
select(columns?: undefined, option?: SelectTableOption): Select<{}>;
|
|
12
|
-
/** 选择全部列 */
|
|
13
|
-
select(columns: "*", option?: SelectTableOption): Select<T>;
|
|
14
|
-
/** 选择表中的列并重命名 */
|
|
15
|
-
select<R extends ColumnsSelectAs<T>>(columns: R, option?: SelectTableOption): Select<SelectColumns<T, R>>;
|
|
10
|
+
fromAs(as?: string): JoinSelect;
|
|
16
11
|
insert(values: C[] | SqlQueryStatement<C>, option?: InsertOption<T>): string;
|
|
17
12
|
insertWithResult<R extends ColumnsSelected<T>>(values: C[] | SqlQueryStatement<C>, returns: R, option?: InsertOption<T>): SqlQueryStatement<SelectColumns<T, R>>;
|
|
18
13
|
update(values: UpdateRowValue<T>, option?: UpdateOption): string;
|
|
@@ -26,14 +21,14 @@ export interface InsertOption<T extends object> {
|
|
|
26
21
|
updateValues?: {
|
|
27
22
|
[key in keyof T]?: undefined | SqlRaw | T[key];
|
|
28
23
|
};
|
|
29
|
-
where?:
|
|
24
|
+
where?: WhereParam;
|
|
30
25
|
}
|
|
31
26
|
/** @public */
|
|
32
27
|
export interface UpdateOption {
|
|
33
|
-
where?:
|
|
28
|
+
where?: WhereParam;
|
|
34
29
|
}
|
|
35
30
|
/** @public */
|
|
36
31
|
export interface DeleteOption {
|
|
37
|
-
where?:
|
|
32
|
+
where?: WhereParam;
|
|
38
33
|
}
|
|
39
34
|
//# sourceMappingURL=TableQuery.d.ts.map
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
import { ColumnsSelectAs
|
|
2
|
-
export declare function genOderBy(orderBy: RowsOrder<any>, orderNullRule?: "FIRST" | "LAST"): string;
|
|
1
|
+
import { ColumnsSelectAs } from "./type.ts";
|
|
3
2
|
export declare function selectColumnsOrTable(columns: ColumnsSelectAs<any> | string[]): {
|
|
4
3
|
columns: string[];
|
|
5
4
|
sqlColumns: string;
|
|
6
5
|
};
|
|
7
|
-
/**
|
|
8
|
-
* @param select 选择的行
|
|
9
|
-
* @param tableColumns 全部行
|
|
10
|
-
* @param push 要讲选择的行加入到集合中。
|
|
11
|
-
*/
|
|
12
|
-
export declare function genNewColumns(select: ColumnsSelected<any>, tableColumns: Iterable<string | number | symbol>,
|
|
13
|
-
/** newName -> oldName */
|
|
14
|
-
push?: Map<string, string | null>): Map<string, string | null>;
|
|
15
6
|
//# sourceMappingURL=_statement.d.ts.map
|
package/dist/select/select.d.ts
CHANGED
|
@@ -1,55 +1,44 @@
|
|
|
1
|
-
import { SqlSelectable,
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
<Q extends SqlSelectable<any>, A extends InferQueryResult<Q>>(tb: Q, columns?: undefined, option?: SelectTableOption): Select<T>;
|
|
5
|
-
<Q extends SqlSelectable<any>, A extends InferQueryResult<Q>, C extends ColumnsSelected<A>>(tb: Q, columns: C, option?: SelectTableOption): Select<T & SelectColumns<A, C>>;
|
|
6
|
-
}
|
|
7
|
-
interface JoinTableFn<T extends TableType, ExtraOption extends object = {}> {
|
|
8
|
-
<Q extends SqlSelectable<any>, A extends InferQueryResult<Q>>(tb: Q, columns: undefined, option: ExtraOption & SelectTableOption): JoinSelect<T>;
|
|
9
|
-
<Q extends SqlSelectable<any>, A extends InferQueryResult<Q>, C extends ColumnsSelected<A>>(tb: Q, columns: C, option: ExtraOption & SelectTableOption): JoinSelect<T & SelectColumns<A, C>>;
|
|
10
|
-
}
|
|
1
|
+
import { SqlSelectable, SqlQueryStatement } from "./selectable.ts";
|
|
2
|
+
import { OrderByParam, WhereParam } from "../util.ts";
|
|
3
|
+
import type { TableType } from "./type.ts";
|
|
11
4
|
/** @public */
|
|
12
5
|
export interface SelectFilterOption<T extends object> {
|
|
13
|
-
orderBy?:
|
|
14
|
-
orderNullRule?: "FIRST" | "LAST";
|
|
15
|
-
where?: string;
|
|
6
|
+
orderBy?: string | OrderByParam<T> | (() => string | OrderByParam<T>);
|
|
16
7
|
offset?: number;
|
|
17
8
|
limit?: number;
|
|
18
9
|
}
|
|
19
10
|
/** @public */
|
|
20
11
|
export interface FinalSelect<T extends TableType> extends SqlSelectable<T> {
|
|
21
|
-
|
|
12
|
+
filter(option: SelectFilterOption<T>): SqlQueryStatement<T>;
|
|
22
13
|
}
|
|
23
14
|
/** @public */
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
[key in keyof
|
|
27
|
-
}): FinalSelect<T
|
|
28
|
-
|
|
29
|
-
naturalJoin: JoinTableFn<T>;
|
|
30
|
-
innerJoin: JoinTableFn<T, {
|
|
31
|
-
on: string;
|
|
32
|
-
}>;
|
|
33
|
-
leftJoin: JoinTableFn<T, {
|
|
34
|
-
on: string;
|
|
35
|
-
}>;
|
|
36
|
-
rightJoin: JoinTableFn<T, {
|
|
37
|
-
on: string;
|
|
38
|
-
}>;
|
|
39
|
-
fullJoin: JoinTableFn<T, {
|
|
40
|
-
on: string;
|
|
41
|
-
}>;
|
|
42
|
-
}
|
|
15
|
+
export type LastSelect = {
|
|
16
|
+
select<T extends TableType = TableType>(columns: "*" | string[] | {
|
|
17
|
+
[key in keyof T]: string | boolean;
|
|
18
|
+
}): FinalSelect<T>;
|
|
19
|
+
};
|
|
43
20
|
/** @public */
|
|
44
|
-
export
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
21
|
+
export type AfterGroup = LastSelect & {
|
|
22
|
+
having(param: WhereParam | (() => WhereParam)): LastSelect;
|
|
23
|
+
};
|
|
24
|
+
/** @public */
|
|
25
|
+
export type AfterWhere = AfterGroup & {
|
|
26
|
+
groupBy(columns: string | string[]): AfterGroup;
|
|
27
|
+
};
|
|
48
28
|
/** @public */
|
|
49
|
-
export
|
|
29
|
+
export type AfterJoin = AfterWhere & {
|
|
30
|
+
where(param: WhereParam | (() => WhereParam)): AfterWhere;
|
|
31
|
+
};
|
|
50
32
|
/** @public */
|
|
51
|
-
export interface
|
|
52
|
-
|
|
33
|
+
export interface JoinSelect extends AfterJoin {
|
|
34
|
+
from(selectable: SqlSelectable<any> | string, as?: string): JoinSelect;
|
|
35
|
+
crossJoin(selectable: SqlSelectable<any> | string, as?: string): JoinSelect;
|
|
36
|
+
naturalJoin(selectable: SqlSelectable<any> | string, as?: string): JoinSelect;
|
|
37
|
+
innerJoin(selectable: SqlSelectable<any> | string, as: string | undefined, on: string): JoinSelect;
|
|
38
|
+
leftJoin(selectable: SqlSelectable<any> | string, as: string | undefined, on: string): JoinSelect;
|
|
39
|
+
rightJoin(selectable: SqlSelectable<any> | string, as: string | undefined, on: string): JoinSelect;
|
|
40
|
+
fullJoin(selectable: SqlSelectable<any> | string, as: string | undefined, on: string): JoinSelect;
|
|
53
41
|
}
|
|
54
|
-
|
|
42
|
+
/** @public */
|
|
43
|
+
export declare function createSelect(selectable: SqlSelectable<any> | string, as?: string): JoinSelect;
|
|
55
44
|
//# sourceMappingURL=select.d.ts.map
|
|
@@ -23,7 +23,7 @@ export declare abstract class SqlSelectable<T extends TableType> {
|
|
|
23
23
|
/** 获取 SQL 语句 */
|
|
24
24
|
abstract toString(): string;
|
|
25
25
|
/** 保留以推断类型 */
|
|
26
|
-
|
|
26
|
+
protected [SQL_SELECTABLE]: T;
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* 数据库表
|
|
@@ -40,8 +40,9 @@ export declare class DbTable<T extends TableType> extends SqlSelectable<T> {
|
|
|
40
40
|
* @public
|
|
41
41
|
*/
|
|
42
42
|
export declare class SqlQueryStatement<T extends TableType = TableType> extends SqlSelectable<T> {
|
|
43
|
-
private
|
|
43
|
+
#private;
|
|
44
44
|
constructor(sql: string, columns: readonly string[]);
|
|
45
|
+
constructor(sql: SqlQueryStatement);
|
|
45
46
|
toString(): string;
|
|
46
47
|
toSelect(): string;
|
|
47
48
|
}
|
package/dist/select/type.d.ts
CHANGED
|
@@ -14,13 +14,6 @@ export type PickColumn<T extends {
|
|
|
14
14
|
} & {
|
|
15
15
|
[key in Pa]?: T[key];
|
|
16
16
|
};
|
|
17
|
-
/**
|
|
18
|
-
* 定义行的排序
|
|
19
|
-
* @public
|
|
20
|
-
*/
|
|
21
|
-
export type RowsOrder<T extends object> = {
|
|
22
|
-
[key in keyof T]?: OrderValue;
|
|
23
|
-
};
|
|
24
17
|
/** @public */
|
|
25
18
|
export type UpdateRowValue<T extends object> = {
|
|
26
19
|
[key in keyof T]?: T[key] | SqlRaw;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SqlSelectable } from "../select/selectable.ts";
|
|
1
2
|
declare const SQL_RAW: unique symbol;
|
|
2
3
|
/**
|
|
3
4
|
* SQL 原始字符对象
|
|
@@ -8,7 +9,7 @@ export declare class SqlRaw<T = any> {
|
|
|
8
9
|
constructor(value: string);
|
|
9
10
|
toString(): string;
|
|
10
11
|
/** 保留以推断类型 */
|
|
11
|
-
|
|
12
|
+
protected [SQL_RAW]: T;
|
|
12
13
|
}
|
|
13
14
|
/** @public */
|
|
14
15
|
export type JsObjectMapSql = Map<new (...args: any[]) => any, SqlValueEncoder>;
|
|
@@ -65,6 +66,22 @@ export declare class SqlValuesCreator {
|
|
|
65
66
|
* @example 返回示例: " 'abc', '6', 'now()' "
|
|
66
67
|
*/
|
|
67
68
|
toValues(values: readonly any[]): string;
|
|
69
|
+
/**
|
|
70
|
+
* @public 创建 VALUES AS 语句
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* sqlValue.createValues(
|
|
74
|
+
* "customName",
|
|
75
|
+
* [{age:8, name:"hhh"}, {age:9, name:"row2"}],
|
|
76
|
+
* {age:"INT", name:"TEXT"}
|
|
77
|
+
* )
|
|
78
|
+
* // (VALUES (8:INT,'hhh':TEXT),(9,'row2')) AS customName(age, name)
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
createValues<T extends {}>(asName: string, values: T[], valuesTypes: Record<string, string | {
|
|
82
|
+
sqlType: string;
|
|
83
|
+
sqlDefault?: string;
|
|
84
|
+
}>): SqlSelectable<T>;
|
|
68
85
|
}
|
|
69
86
|
export {};
|
|
70
87
|
//# sourceMappingURL=sql_value.d.ts.map
|
package/dist/util.d.ts
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
|
+
import { OrderValue } from "./select/type.ts";
|
|
1
2
|
/**
|
|
2
3
|
* @public
|
|
3
4
|
* @param keepUndefinedKey - 是否保留值为 undefined 的 key
|
|
4
5
|
*/
|
|
5
6
|
export declare function getObjectListKeys(objectList: any[], keepUndefinedKey?: boolean): string[];
|
|
7
|
+
/** @public */
|
|
8
|
+
export type WhereParam = string | string[];
|
|
9
|
+
/** @public */
|
|
10
|
+
export declare function genWhere(where: WhereParam | (() => WhereParam), type?: "AND" | "OR"): string;
|
|
11
|
+
/** @public */
|
|
12
|
+
export declare function genHaving(having: WhereParam | (() => WhereParam), type?: "AND" | "OR"): string;
|
|
13
|
+
/**
|
|
14
|
+
* @public
|
|
15
|
+
* ```ts
|
|
16
|
+
* genSelect({c1: true, c2: "count(*)", c3: "column"}) // "c1,count(*) AS c2,column as c3"
|
|
17
|
+
* genSelect(["c1", "count(*) AS c2", "column as c3"]) // "c1,count(*) AS c2,column as c3"
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function genSelect(columns: string[] | Record<string, string | boolean>): string;
|
|
21
|
+
/** @public */
|
|
22
|
+
export type OrderByParam<T extends {} = {}> = string | string[] | ({
|
|
23
|
+
[key in keyof T]: OrderValue;
|
|
24
|
+
} & Record<string, OrderValue>);
|
|
25
|
+
/** @public */
|
|
26
|
+
export declare function genOderBy<T extends {} = {}>(orderBy: OrderByParam<T> | (() => OrderByParam<T>)): string;
|
|
6
27
|
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ColumnMeta } from "./infer_db_type.ts";
|
|
2
|
+
/** @public */
|
|
3
|
+
export declare class TypeChecker<T> {
|
|
4
|
+
private map;
|
|
5
|
+
constructor(map: Map<string, ColumnMeta<any>>);
|
|
6
|
+
check(value: {
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}): T;
|
|
9
|
+
checkList(value: any[]): T[];
|
|
10
|
+
private checkArray;
|
|
11
|
+
private checkItem;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=checker.d.ts.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 表格列的信息
|
|
3
|
+
* @public
|
|
4
|
+
*/
|
|
5
|
+
export declare class ColumnMeta<T> {
|
|
6
|
+
readonly type: CustomDbType<T> | (new (...args: any[]) => T);
|
|
7
|
+
/** 数据库原始数据类型 */
|
|
8
|
+
readonly sqlType: string;
|
|
9
|
+
/** 是否非空 */
|
|
10
|
+
readonly notNull: boolean;
|
|
11
|
+
/** 是否是数组类型 */
|
|
12
|
+
readonly isArray: boolean;
|
|
13
|
+
/** 数据库原始默认值 */
|
|
14
|
+
readonly sqlDefault?: string | undefined;
|
|
15
|
+
constructor(type: CustomDbType<T> | (new (...args: any[]) => T),
|
|
16
|
+
/** 数据库原始数据类型 */
|
|
17
|
+
sqlType: string,
|
|
18
|
+
/** 是否非空 */
|
|
19
|
+
notNull?: boolean,
|
|
20
|
+
/** 是否是数组类型 */
|
|
21
|
+
isArray?: boolean,
|
|
22
|
+
/** 数据库原始默认值 */
|
|
23
|
+
sqlDefault?: string | undefined);
|
|
24
|
+
/** 校验 value 的类型 */
|
|
25
|
+
checkValue(value: any): boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 数据库类型到JS类型的映射
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export declare class YourTypeMap<M extends TypeMapDefined> {
|
|
32
|
+
private readonly typeMap;
|
|
33
|
+
static create<T extends TypeMapDefined>(rawTypeMap?: T): YourTypeMap<{
|
|
34
|
+
[key in keyof T]: InferTypeMapDefined<T[key]>;
|
|
35
|
+
}>;
|
|
36
|
+
constructor(typeMap?: M);
|
|
37
|
+
genColumn<T extends keyof M>(type: T, noNull: true, defaultValue?: string): ColumnMeta<M[T]>;
|
|
38
|
+
genColumn<T extends keyof M>(type: T, noNull?: boolean, defaultValue?: string): ColumnMeta<M[T] | null>;
|
|
39
|
+
genColumn<T>(type: keyof M, noNull: true, defaultValue?: string): ColumnMeta<T>;
|
|
40
|
+
genColumn<T>(type: keyof M, noNull?: boolean, defaultValue?: string): ColumnMeta<T | null>;
|
|
41
|
+
genArrColumn<T extends keyof M>(type: T, noNull: true, defaultValue?: string): ColumnMeta<M[T][]>;
|
|
42
|
+
genArrColumn<T extends keyof M>(type: T, noNull?: boolean, defaultValue?: string): ColumnMeta<M[T][] | null>;
|
|
43
|
+
genArrColumn<T>(type: keyof M, notNull: true, defaultValue?: string): ColumnMeta<T[]>;
|
|
44
|
+
genArrColumn<T>(type: keyof M, notNull?: boolean, defaultValue?: string): ColumnMeta<T[] | null>;
|
|
45
|
+
}
|
|
46
|
+
type Constructor<T = any> = new (...args: any[]) => T;
|
|
47
|
+
/**
|
|
48
|
+
* 自定义数据类型
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
export declare class CustomDbType<T> {
|
|
52
|
+
readonly is: (this: CustomDbType<T>, value: any) => boolean;
|
|
53
|
+
readonly name: string;
|
|
54
|
+
static readonly bigint: CustomDbType<bigint>;
|
|
55
|
+
static readonly number: CustomDbType<number>;
|
|
56
|
+
static readonly string: CustomDbType<string>;
|
|
57
|
+
static readonly boolean: CustomDbType<boolean>;
|
|
58
|
+
constructor(is: (this: CustomDbType<T>, value: any) => boolean, name: string);
|
|
59
|
+
}
|
|
60
|
+
type TypeMapDefined = {
|
|
61
|
+
[key: string]: Constructor | CustomDbType<any>;
|
|
62
|
+
};
|
|
63
|
+
type InferTypeMapDefined<T> = T extends Constructor<infer P> ? TRaw<P> : T extends CustomDbType<infer Q> ? Q : never;
|
|
64
|
+
type TRaw<T> = T extends Number ? number : T extends BigInt ? bigint : T extends String ? string : T extends Boolean ? boolean : T;
|
|
65
|
+
/** @public */
|
|
66
|
+
export type TableDefined = {
|
|
67
|
+
[key: string]: ColumnMeta<any>;
|
|
68
|
+
};
|
|
69
|
+
/** @public */
|
|
70
|
+
export type InferTableDefined<T extends TableDefined> = {
|
|
71
|
+
[key in keyof T]: T[key] extends ColumnMeta<infer P> ? P : unknown;
|
|
72
|
+
};
|
|
73
|
+
export {};
|
|
74
|
+
//# sourceMappingURL=infer_db_type.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DbTableQuery } from "../select/TableQuery.ts";
|
|
2
|
+
import type { TableType } from "../select/type.ts";
|
|
3
|
+
import type { SqlValuesCreator } from "../sql_value/sql_value.ts";
|
|
4
|
+
import type { ColumnMeta, TableDefined } from "./infer_db_type.ts";
|
|
5
|
+
import { TypeChecker } from "./checker.ts";
|
|
6
|
+
/**
|
|
7
|
+
* 完整数据库表数据
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare class YourTable<T extends TableType = TableType, C extends TableType = T> extends DbTableQuery<T, C> {
|
|
11
|
+
private define;
|
|
12
|
+
constructor(name: string, define: TableDefined, sqlValue: SqlValuesCreator);
|
|
13
|
+
getColumnMeta(name: keyof T): ColumnMeta<unknown>;
|
|
14
|
+
createTypeChecker<T>(keys: readonly string[]): TypeChecker<T>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=table.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asla/yoursql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/mod.d.ts",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"build": "pnpm rollup -c build/rollup.config.js && pnpm run ci:check-api -l",
|
|
11
11
|
"test": "vitest",
|
|
12
12
|
"type:check": "tsc",
|
|
13
|
+
"publish-check": "deno publish --dry-run --allow-dirty",
|
|
13
14
|
"ci:check-api": "api-extractor run -c api-extractor.jsonc -v"
|
|
14
15
|
},
|
|
15
16
|
"devDependencies": {
|