befly 3.20.8 → 3.20.9

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.
@@ -7,13 +7,102 @@ import { addDefaultStateFilter, buildInsertRow, buildPartialUpdateData, buildUpd
7
7
  import { assertBatchInsertRowsConsistent, assertNoUndefinedInRecord, validateGeneratedBatchId, validateIncrementOptions, validateInsertBatchSize, validateNoLeftJoinReadOptions, validatePageLimitRange, validateSafeFieldName, validateTableBatchDataOptions, validateTableDataOptions, validateTableName, validateTableWhereOptions } from "./validate.js";
8
8
 
9
9
  export const dataOpsMethods = {
10
+ prepareSingleTableWhere(table, where, useDefaultStateFilter = true) {
11
+ const snakeTable = snakeCase(table);
12
+ const snakeWhere = whereKeysToSnake(clearDeep(where || {}));
13
+
14
+ return {
15
+ snakeTable: snakeTable,
16
+ whereFiltered: useDefaultStateFilter ? addDefaultStateFilter(snakeWhere, snakeTable, false, this.beflyMode) : snakeWhere
17
+ };
18
+ },
19
+
20
+ async createInsertRows(table, snakeTable, dataList, now) {
21
+ if (this.beflyMode === "manual") {
22
+ return {
23
+ ids: [],
24
+ processedList: dataList.map((data) =>
25
+ buildInsertRow({
26
+ data: data,
27
+ now: now,
28
+ beflyMode: this.beflyMode
29
+ })
30
+ )
31
+ };
32
+ }
33
+
34
+ const ids = [];
35
+ try {
36
+ for (let i = 0; i < dataList.length; i++) {
37
+ ids.push(await this.redis.genTimeID());
38
+ }
39
+ } catch (error) {
40
+ if (dataList.length === 1) {
41
+ throw new Error(`生成 ID 失败,Redis 可能不可用 (table: ${table})`, {
42
+ cause: error,
43
+ code: "runtime",
44
+ subsystem: "db",
45
+ operation: "genTimeId",
46
+ table: table
47
+ });
48
+ }
49
+ throw error;
50
+ }
51
+
52
+ const processedList = dataList.map((data, index) => {
53
+ const id = ids[index];
54
+ if (dataList.length > 1) {
55
+ validateGeneratedBatchId(id, snakeTable, index);
56
+ }
57
+
58
+ return buildInsertRow({
59
+ data: data,
60
+ id: id,
61
+ now: now,
62
+ beflyMode: this.beflyMode
63
+ });
64
+ });
65
+
66
+ return {
67
+ ids: ids,
68
+ processedList: processedList
69
+ };
70
+ },
71
+
72
+ resolveInsertedData(table, count, executeRes, generatedIds, operation) {
73
+ const lastInsertRowidNum = normalizeSqlMetaNumber(executeRes.data?.lastInsertRowid);
74
+
75
+ if (this.beflyMode === "manual") {
76
+ if (lastInsertRowidNum <= 0) {
77
+ throw new Error(operation === "insBatch" ? `批量插入失败:beflyMode=manual 时无法获取 lastInsertRowid (table: ${table})` : `插入失败:beflyMode=manual 时无法获取 lastInsertRowid (table: ${table})`, {
78
+ cause: null,
79
+ code: "runtime"
80
+ });
81
+ }
82
+
83
+ if (count === 1) {
84
+ return lastInsertRowidNum;
85
+ }
86
+
87
+ const outIds = [];
88
+ for (let i = 0; i < count; i++) {
89
+ outIds.push(lastInsertRowidNum + i);
90
+ }
91
+ return outIds;
92
+ }
93
+
94
+ if (count === 1) {
95
+ const generatedId = generatedIds[0];
96
+ return (isNumber(generatedId) ? generatedId : 0) || lastInsertRowidNum || 0;
97
+ }
98
+
99
+ return generatedIds;
100
+ },
101
+
10
102
  // 读取操作
11
103
  async getCount(options) {
12
- const { table, where, leftJoins, tableQualifier } = await this.prepareQueryOptions(options, "getCount.options");
13
- const hasLeftJoin = Array.isArray(leftJoins) && leftJoins.length > 0;
14
-
15
- const whereFiltered = addDefaultStateFilter(where, tableQualifier, hasLeftJoin, this.beflyMode);
16
- const result = await this.fetchCount({ table: table, leftJoins: leftJoins }, whereFiltered, "COUNT(*) as count");
104
+ const { prepared, whereFiltered } = await this.prepareReadContext(options, "getCount.options");
105
+ const result = await this.fetchCount(prepared, whereFiltered, "COUNT(*) as count");
17
106
 
18
107
  return {
19
108
  data: result.total,
@@ -22,12 +111,9 @@ export const dataOpsMethods = {
22
111
  },
23
112
 
24
113
  async getOne(options) {
25
- const { table, fields, where, leftJoins, tableQualifier } = await this.prepareQueryOptions(options, "getOne.options");
26
- const hasLeftJoin = Array.isArray(leftJoins) && leftJoins.length > 0;
27
-
28
- const whereFiltered = addDefaultStateFilter(where, tableQualifier, hasLeftJoin, this.beflyMode);
29
- const builder = this.createSqlBuilder().select(fields).from(table).where(whereFiltered);
30
- this.applyLeftJoins(builder, leftJoins);
114
+ const { prepared, whereFiltered } = await this.prepareReadContext(options, "getOne.options");
115
+ const builder = this.createSqlBuilder().select(prepared.fields).from(prepared.table).where(whereFiltered);
116
+ this.applyLeftJoins(builder, prepared.leftJoins);
31
117
 
32
118
  const { sql, params } = builder.toSelectSql();
33
119
  const executeRes = await this.execute(sql, params);
@@ -45,11 +131,8 @@ export const dataOpsMethods = {
45
131
  },
46
132
 
47
133
  async getList(options) {
48
- const prepared = await this.prepareQueryOptions(options, "getList.options");
134
+ const { prepared, whereFiltered } = await this.prepareReadContext(options, "getList.options");
49
135
  validatePageLimitRange(prepared, options.table);
50
-
51
- const hasLeftJoin = Array.isArray(prepared.leftJoins) && prepared.leftJoins.length > 0;
52
- const whereFiltered = addDefaultStateFilter(prepared.where, prepared.tableQualifier, hasLeftJoin, this.beflyMode);
53
136
  const countResult = await this.fetchCount(prepared, whereFiltered, "COUNT(*) as total");
54
137
  const total = countResult.total;
55
138
 
@@ -98,10 +181,7 @@ export const dataOpsMethods = {
98
181
  const MAX_LIMIT = 100000;
99
182
  const WARNING_LIMIT = 10000;
100
183
  const prepareOptions = this.buildQueryOptions(options, { page: 1, limit: 10 });
101
- const prepared = await this.prepareQueryOptions(prepareOptions, "getAll.options");
102
-
103
- const hasLeftJoin = Array.isArray(prepared.leftJoins) && prepared.leftJoins.length > 0;
104
- const whereFiltered = addDefaultStateFilter(prepared.where, prepared.tableQualifier, hasLeftJoin, this.beflyMode);
184
+ const { prepared, whereFiltered } = await this.prepareReadContext(prepareOptions, "getAll.options");
105
185
  const countResult = await this.fetchCount(prepared, whereFiltered, "COUNT(*) as total");
106
186
  const total = countResult.total;
107
187
 
@@ -147,11 +227,9 @@ export const dataOpsMethods = {
147
227
 
148
228
  async exists(options) {
149
229
  validateNoLeftJoinReadOptions(options, "exists", "exists 不支持 leftJoin(请使用显式 query 或拆分查询)");
150
- const snakeTable = snakeCase(options.table);
151
- const snakeWhere = whereKeysToSnake(clearDeep(options.where || {}));
152
- const whereFiltered = addDefaultStateFilter(snakeWhere, snakeTable, false, this.beflyMode);
230
+ const prepared = this.prepareSingleTableWhere(options.table, options.where, true);
153
231
 
154
- const builder = this.createSqlBuilder().selectRaw("COUNT(1) as cnt").from(snakeTable).where(whereFiltered).limit(1);
232
+ const builder = this.createSqlBuilder().selectRaw("COUNT(1) as cnt").from(prepared.snakeTable).where(prepared.whereFiltered).limit(1);
155
233
  const { sql, params } = builder.toSelectSql();
156
234
  const executeRes = await this.execute(sql, params);
157
235
  const exists = (executeRes.data?.[0]?.cnt || 0) > 0;
@@ -190,34 +268,8 @@ export const dataOpsMethods = {
190
268
  const { table, data } = options;
191
269
  const snakeTable = snakeCase(table);
192
270
  const now = Date.now();
193
-
194
- let processed;
195
- if (this.beflyMode === "manual") {
196
- processed = buildInsertRow({
197
- data: data,
198
- now: now,
199
- beflyMode: this.beflyMode
200
- });
201
- } else {
202
- let id;
203
- try {
204
- id = await this.redis.genTimeID();
205
- } catch (error) {
206
- throw new Error(`生成 ID 失败,Redis 可能不可用 (table: ${table})`, {
207
- cause: error,
208
- code: "runtime",
209
- subsystem: "db",
210
- operation: "genTimeId",
211
- table: table
212
- });
213
- }
214
- processed = buildInsertRow({
215
- data: data,
216
- id: id,
217
- now: now,
218
- beflyMode: this.beflyMode
219
- });
220
- }
271
+ const insertRows = await this.createInsertRows(table, snakeTable, [data], now);
272
+ const processed = insertRows.processedList[0];
221
273
 
222
274
  assertNoUndefinedInRecord(processed, `insData 插入数据 (table: ${snakeTable})`);
223
275
 
@@ -225,19 +277,8 @@ export const dataOpsMethods = {
225
277
  const { sql, params } = builder.toInsertSql(snakeTable, processed);
226
278
  const executeRes = await this.execute(sql, params);
227
279
 
228
- const processedId = processed["id"];
229
- const processedIdNum = isNumber(processedId) ? processedId : 0;
230
- const lastInsertRowidNum = normalizeSqlMetaNumber(executeRes.data?.lastInsertRowid);
231
-
232
- const insertedId = this.beflyMode === "manual" ? lastInsertRowidNum || 0 : processedIdNum || lastInsertRowidNum || 0;
233
- if (this.beflyMode === "manual" && insertedId <= 0) {
234
- throw new Error(`插入失败:beflyMode=manual 时无法获取 lastInsertRowid (table: ${table})`, {
235
- cause: null,
236
- code: "runtime"
237
- });
238
- }
239
280
  return {
240
- data: insertedId,
281
+ data: this.resolveInsertedData(table, 1, executeRes, insertRows.ids, "insData"),
241
282
  sql: executeRes.sql
242
283
  };
243
284
  },
@@ -256,25 +297,8 @@ export const dataOpsMethods = {
256
297
 
257
298
  const snakeTable = snakeCase(table);
258
299
  const now = Date.now();
259
- let ids = [];
260
-
261
- let processedList;
262
- if (this.beflyMode === "manual") {
263
- processedList = dataList.map((data) => {
264
- return buildInsertRow({ data: data, now: now, beflyMode: this.beflyMode });
265
- });
266
- } else {
267
- const nextIds = [];
268
- for (let i = 0; i < dataList.length; i++) {
269
- nextIds.push(await this.redis.genTimeID());
270
- }
271
- ids = nextIds;
272
- processedList = dataList.map((data, index) => {
273
- const id = nextIds[index];
274
- validateGeneratedBatchId(id, snakeTable, index);
275
- return buildInsertRow({ data: data, id: id, now: now, beflyMode: this.beflyMode });
276
- });
277
- }
300
+ const insertRows = await this.createInsertRows(table, snakeTable, dataList, now);
301
+ const processedList = insertRows.processedList;
278
302
 
279
303
  const insertFields = assertBatchInsertRowsConsistent(processedList, { table: snakeTable });
280
304
  const builder = this.createSqlBuilder();
@@ -282,29 +306,8 @@ export const dataOpsMethods = {
282
306
 
283
307
  try {
284
308
  const executeRes = await this.execute(sql, params);
285
-
286
- if (this.beflyMode === "manual") {
287
- const firstId = normalizeSqlMetaNumber(executeRes.data?.lastInsertRowid);
288
- if (firstId <= 0) {
289
- throw new Error(`批量插入失败:beflyMode=manual 时无法获取 lastInsertRowid (table: ${table})`, {
290
- cause: null,
291
- code: "runtime"
292
- });
293
- }
294
-
295
- const outIds = [];
296
- for (let i = 0; i < dataList.length; i++) {
297
- outIds.push(firstId + i);
298
- }
299
-
300
- return {
301
- data: outIds,
302
- sql: executeRes.sql
303
- };
304
- }
305
-
306
309
  return {
307
- data: ids,
310
+ data: this.resolveInsertedData(table, dataList.length, executeRes, insertRows.ids, "insBatch"),
308
311
  sql: executeRes.sql
309
312
  };
310
313
  } catch (error) {
@@ -409,13 +412,11 @@ export const dataOpsMethods = {
409
412
  validateTableDataOptions(options, "updData");
410
413
  validateTableWhereOptions(options, "updData", true);
411
414
  const { table, data, where } = options;
412
- const snakeTable = snakeCase(table);
413
- const snakeWhere = whereKeysToSnake(clearDeep(where));
415
+ const prepared = this.prepareSingleTableWhere(table, where, true);
414
416
 
415
417
  const processed = buildUpdateRow({ data: data, now: Date.now(), allowState: true, beflyMode: this.beflyMode });
416
- const whereFiltered = addDefaultStateFilter(snakeWhere, snakeTable, false, this.beflyMode);
417
- const builder = this.createSqlBuilder().where(whereFiltered);
418
- const { sql, params } = builder.toUpdateSql(snakeTable, processed);
418
+ const builder = this.createSqlBuilder().where(prepared.whereFiltered);
419
+ const { sql, params } = builder.toUpdateSql(prepared.snakeTable, processed);
419
420
 
420
421
  const executeRes = await this.execute(sql, params);
421
422
  const changes = normalizeSqlMetaNumber(executeRes.data?.affectedRows);
@@ -428,8 +429,7 @@ export const dataOpsMethods = {
428
429
  async delData(options) {
429
430
  validateTableWhereOptions(options, "delData", true);
430
431
  const { table, where } = options;
431
- const snakeTable = snakeCase(table);
432
- const snakeWhere = whereKeysToSnake(clearDeep(where));
432
+ const prepared = this.prepareSingleTableWhere(table, where, true);
433
433
  const now = Date.now();
434
434
  const processed = {
435
435
  state: 0,
@@ -440,9 +440,8 @@ export const dataOpsMethods = {
440
440
  processed.updated_at = now;
441
441
  }
442
442
 
443
- const whereFiltered = addDefaultStateFilter(snakeWhere, snakeTable, false, this.beflyMode);
444
- const builder = this.createSqlBuilder().where(whereFiltered);
445
- const { sql, params } = builder.toUpdateSql(snakeTable, processed);
443
+ const builder = this.createSqlBuilder().where(prepared.whereFiltered);
444
+ const { sql, params } = builder.toUpdateSql(prepared.snakeTable, processed);
446
445
  const executeRes = await this.execute(sql, params);
447
446
  const changes = normalizeSqlMetaNumber(executeRes.data?.affectedRows);
448
447
 
@@ -456,11 +455,10 @@ export const dataOpsMethods = {
456
455
  validateTableWhereOptions(options, "delForce", true);
457
456
  const { table, where } = options;
458
457
 
459
- const snakeTable = snakeCase(table);
460
- const snakeWhere = whereKeysToSnake(clearDeep(where));
458
+ const prepared = this.prepareSingleTableWhere(table, where, false);
461
459
 
462
- const builder = this.createSqlBuilder().where(snakeWhere);
463
- const { sql, params } = builder.toDeleteSql(snakeTable);
460
+ const builder = this.createSqlBuilder().where(prepared.whereFiltered);
461
+ const { sql, params } = builder.toDeleteSql(prepared.snakeTable);
464
462
 
465
463
  const executeRes = await this.execute(sql, params);
466
464
  const changes = normalizeSqlMetaNumber(executeRes.data?.affectedRows);
@@ -498,15 +496,13 @@ export const dataOpsMethods = {
498
496
 
499
497
  async increment(table, field, where, value = 1) {
500
498
  validateIncrementOptions(table, field, where, value, "increment");
501
- const snakeTable = snakeCase(table);
499
+ const prepared = this.prepareSingleTableWhere(table, where, true);
502
500
  const snakeField = snakeCase(field);
503
501
 
504
- const snakeWhere = whereKeysToSnake(clearDeep(where));
505
- const whereFiltered = addDefaultStateFilter(snakeWhere, snakeTable, false, this.beflyMode);
506
- const builder = this.createSqlBuilder().where(whereFiltered);
502
+ const builder = this.createSqlBuilder().where(prepared.whereFiltered);
507
503
  const { sql: whereClause, params: whereParams } = builder.getWhereConditions();
508
504
 
509
- const quotedTable = quoteIdentMySql(snakeTable);
505
+ const quotedTable = quoteIdentMySql(prepared.snakeTable);
510
506
  const quotedField = quoteIdentMySql(snakeField);
511
507
  const sql = whereClause ? `UPDATE ${quotedTable} SET ${quotedField} = ${quotedField} + ? WHERE ${whereClause}` : `UPDATE ${quotedTable} SET ${quotedField} = ${quotedField} + ?`;
512
508
 
@@ -1,6 +1,39 @@
1
1
  import { isFiniteNumber, isNonEmptyString, isNullable, isPlainObject, isString } from "../../utils/is.js";
2
2
  import { snakeCase } from "../../utils/util.js";
3
3
 
4
+ function validateJoinFieldRef(value, label) {
5
+ if (!isNonEmptyString(value)) {
6
+ throw new Error(`${label} 不能为空`, {
7
+ cause: null,
8
+ code: "validation"
9
+ });
10
+ }
11
+
12
+ const parts = value.split(".").map((item) => item.trim());
13
+ if (parts.length !== 2 || !isNonEmptyString(parts[0]) || !isNonEmptyString(parts[1])) {
14
+ throw new Error(`${label} 必须是 alias.field 格式`, {
15
+ cause: null,
16
+ code: "validation"
17
+ });
18
+ }
19
+ }
20
+
21
+ function parseLeftJoinEquality(joinItem) {
22
+ if (!isNonEmptyString(joinItem)) {
23
+ return null;
24
+ }
25
+
26
+ const match = joinItem.match(/^([a-zA-Z_][a-zA-Z0-9_]*\.[a-zA-Z_][a-zA-Z0-9_]*) ([a-zA-Z_][a-zA-Z0-9_]*\.[a-zA-Z_][a-zA-Z0-9_]*)$/);
27
+ if (!match) {
28
+ return null;
29
+ }
30
+
31
+ return {
32
+ left: match[1],
33
+ right: match[2]
34
+ };
35
+ }
36
+
4
37
  function assertNonEmptyString(value, label) {
5
38
  if (!isNonEmptyString(value)) {
6
39
  throw new Error(`${label} 必须是非空字符串`, {
@@ -147,30 +180,60 @@ function validateLeftJoinItems(leftJoin, label) {
147
180
  });
148
181
  }
149
182
 
150
- const parts = joinItem.split(/\s+ON\s+/i);
151
- if (parts.length !== 2) {
152
- throw new Error(`${label}[${i}] 必须是 "table alias ON left.field = right.field" 格式`, {
183
+ const parsed = parseLeftJoinEquality(joinItem);
184
+ if (!parsed) {
185
+ throw new Error(`${label}[${i}] 必须是 "left.field right.field" 格式(空格表示等于)`, {
153
186
  cause: null,
154
187
  code: "validation"
155
188
  });
156
189
  }
157
190
 
158
- const tableRef = parts[0]?.trim();
159
- const on = parts[1]?.trim();
160
- if (!isNonEmptyString(tableRef)) {
161
- throw new Error(`${label}[${i}] 缺少 leftJoin 表名`, {
191
+ validateJoinFieldRef(parsed.left, `${label}[${i}] 左侧字段`);
192
+ validateJoinFieldRef(parsed.right, `${label}[${i}] 右侧字段`);
193
+ }
194
+ }
195
+
196
+ function validateQueryTableOption(table, leftJoin, label) {
197
+ if (Array.isArray(table)) {
198
+ if (table.length === 0) {
199
+ throw new Error(`${label}.table 不能为空数组`, {
162
200
  cause: null,
163
201
  code: "validation"
164
202
  });
165
203
  }
166
- if (!isNonEmptyString(on)) {
167
- throw new Error(`${label}[${i}] 缺少 leftJoin ON 条件`, {
204
+
205
+ for (let i = 0; i < table.length; i++) {
206
+ assertNonEmptyString(table[i], `${label}.table[${i}]`);
207
+ parseTableRef(table[i]);
208
+ }
209
+
210
+ if (Array.isArray(leftJoin) && leftJoin.length > 0) {
211
+ if (table.length !== leftJoin.length + 1) {
212
+ throw new Error(`${label}.table 与 ${label}.leftJoin 数量不匹配,要求 table.length = leftJoin.length + 1`, {
213
+ cause: null,
214
+ code: "validation"
215
+ });
216
+ }
217
+ return;
218
+ }
219
+
220
+ if (table.length > 1) {
221
+ throw new Error(`${label}.table 为数组时必须配合 leftJoin 使用`, {
168
222
  cause: null,
169
223
  code: "validation"
170
224
  });
171
225
  }
226
+ return;
227
+ }
172
228
 
173
- parseTableRef(tableRef);
229
+ assertNonEmptyString(table, `${label}.table`);
230
+ parseTableRef(table);
231
+
232
+ if (Array.isArray(leftJoin) && leftJoin.length > 0) {
233
+ throw new Error(`${label}.leftJoin 启用时,${label}.table 必须是数组`, {
234
+ cause: null,
235
+ code: "validation"
236
+ });
174
237
  }
175
238
  }
176
239
 
@@ -194,7 +257,7 @@ export function validateQueryOptions(options, label) {
194
257
  });
195
258
  }
196
259
 
197
- assertNonEmptyString(options.table, `${label}.table`);
260
+ validateQueryTableOption(options.table, options.leftJoin, label);
198
261
 
199
262
  if (!isNullable(options.where)) {
200
263
  validateWhereObject(options.where, `${label}.where`);
@@ -232,11 +295,7 @@ export function validateQueryOptions(options, label) {
232
295
  }
233
296
  }
234
297
 
235
- export function validateWriteData(data, label) {
236
- assertPlainObjectValue(data, label);
237
- }
238
-
239
- export function validateBatchDataList(dataList, label) {
298
+ function validateBatchDataList(dataList, label) {
240
299
  if (!Array.isArray(dataList)) {
241
300
  throw new Error(`${label} 必须是数组`, {
242
301
  cause: null,
@@ -265,7 +324,7 @@ export function validateTableWhereOptions(options, label, required = false) {
265
324
 
266
325
  export function validateTableDataOptions(options, label) {
267
326
  validateTableName(options.table, `${label}.table`);
268
- validateWriteData(options.data, `${label}.data`);
327
+ assertPlainObjectValue(options.data, `${label}.data`);
269
328
  }
270
329
 
271
330
  export function validateTableBatchDataOptions(table, dataList, label) {
@@ -274,20 +333,29 @@ export function validateTableBatchDataOptions(table, dataList, label) {
274
333
  }
275
334
 
276
335
  export function validateNoLeftJoinReadOptions(options, label, joinErrorMessage) {
277
- validateTableWhereOptions(options, label, false);
336
+ validateTableName(options.table, `${label}.table`);
337
+ validateWhereObject(options.where, `${label}.where`, false);
278
338
  validateNoLeftJoin(options.leftJoin, joinErrorMessage);
279
339
  validateLegacyJoinOptions(options, label);
280
340
  validateSimpleTableName(options.table, label);
281
341
  }
282
342
 
283
343
  export function validateIncrementOptions(table, field, where, value, label) {
284
- validateTableWhereOptions({ table: table, where: where }, label, true);
344
+ validateTableName(table, `${label}.table`);
345
+ validateWhereObject(where, `${label}.where`, true);
285
346
  validateSafeFieldName(snakeCase(table));
286
347
  validateSafeFieldName(snakeCase(field));
287
348
  validateIncrementValue(table, field, value);
288
349
  }
289
350
 
290
351
  export function validateSimpleTableName(rawTable, label) {
352
+ if (Array.isArray(rawTable)) {
353
+ throw new Error(`${label}.table 不支持数组`, {
354
+ cause: null,
355
+ code: "validation"
356
+ });
357
+ }
358
+
291
359
  const table = isString(rawTable) ? rawTable.trim() : "";
292
360
  if (!table) {
293
361
  throw new Error(`${label}.table 不能为空`, {
@@ -319,7 +387,7 @@ export function validateSafeFieldName(field) {
319
387
  }
320
388
 
321
389
  export function validatePageLimitRange(prepared, rawTable) {
322
- if (prepared.page < 1 || prepared.page > 100000) {
390
+ if (prepared.page < 1 || prepared.page > 10000) {
323
391
  throw new Error(`页码必须在 1 到 10000 之间 (table: ${rawTable}, page: ${prepared.page}, limit: ${prepared.limit})`, {
324
392
  cause: null,
325
393
  code: "validation"
@@ -1,22 +1,21 @@
1
- import { SqlErrors } from "./errors.js";
2
1
  import { isNonEmptyString } from "../../utils/is.js";
3
2
  import { SqlCheck } from "./check.js";
4
3
 
5
4
  export function toDeleteInSql(options) {
6
5
  if (!isNonEmptyString(options.table)) {
7
- throw new Error(SqlErrors.TO_DELETE_IN_NEED_TABLE(options.table), {
6
+ throw new Error(`toDeleteInSql 需要非空表名 (table: ${String(options.table)})`, {
8
7
  cause: null,
9
8
  code: "validation"
10
9
  });
11
10
  }
12
11
  if (!isNonEmptyString(options.idField)) {
13
- throw new Error(SqlErrors.TO_DELETE_IN_NEED_ID_FIELD(options.idField), {
12
+ throw new Error(`toDeleteInSql 需要非空 idField (idField: ${String(options.idField)})`, {
14
13
  cause: null,
15
14
  code: "validation"
16
15
  });
17
16
  }
18
17
  if (!Array.isArray(options.ids)) {
19
- throw new Error(SqlErrors.TO_DELETE_IN_NEED_IDS, {
18
+ throw new Error("toDeleteInSql 需要 ids 数组", {
20
19
  cause: null,
21
20
  code: "validation"
22
21
  });
@@ -36,19 +35,19 @@ export function toDeleteInSql(options) {
36
35
 
37
36
  export function toUpdateCaseByIdSql(options) {
38
37
  if (!isNonEmptyString(options.table)) {
39
- throw new Error(SqlErrors.TO_UPDATE_CASE_NEED_TABLE(options.table), {
38
+ throw new Error(`toUpdateCaseByIdSql 需要非空表名 (table: ${String(options.table)})`, {
40
39
  cause: null,
41
40
  code: "validation"
42
41
  });
43
42
  }
44
43
  if (!isNonEmptyString(options.idField)) {
45
- throw new Error(SqlErrors.TO_UPDATE_CASE_NEED_ID_FIELD(options.idField), {
44
+ throw new Error(`toUpdateCaseByIdSql 需要非空 idField (idField: ${String(options.idField)})`, {
46
45
  cause: null,
47
46
  code: "validation"
48
47
  });
49
48
  }
50
49
  if (!Array.isArray(options.rows)) {
51
- throw new Error(SqlErrors.TO_UPDATE_CASE_NEED_ROWS, {
50
+ throw new Error("toUpdateCaseByIdSql 需要 rows 数组", {
52
51
  cause: null,
53
52
  code: "validation"
54
53
  });
@@ -57,7 +56,7 @@ export function toUpdateCaseByIdSql(options) {
57
56
  return { sql: "", params: [] };
58
57
  }
59
58
  if (!Array.isArray(options.fields)) {
60
- throw new Error(SqlErrors.TO_UPDATE_CASE_NEED_FIELDS, {
59
+ throw new Error("toUpdateCaseByIdSql 需要 fields 数组", {
61
60
  cause: null,
62
61
  code: "validation"
63
62
  });