@objectstack/driver-sql 7.9.0 → 8.0.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/index.d.mts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +25 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +25 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -85,6 +85,7 @@ declare class SqlDriver implements IDataDriver {
|
|
|
85
85
|
jsonFields: boolean;
|
|
86
86
|
arrayFields: boolean;
|
|
87
87
|
vectorSearch: boolean;
|
|
88
|
+
autonumber: boolean;
|
|
88
89
|
schemaSync: boolean;
|
|
89
90
|
batchSchemaSync: boolean;
|
|
90
91
|
migrations: boolean;
|
|
@@ -419,6 +420,15 @@ declare class SqlDriver implements IDataDriver {
|
|
|
419
420
|
*/
|
|
420
421
|
protected coerceFilterValue(table: string | null, field: string, value: any): any;
|
|
421
422
|
protected applyFilters(builder: Knex.QueryBuilder, filters: any): void;
|
|
423
|
+
/**
|
|
424
|
+
* Apply a `contains` substring match as a parameterized `LIKE '%…%'`, escaping
|
|
425
|
+
* the LIKE metacharacters `%` / `_` (and the escape char `\`) in the user value
|
|
426
|
+
* so they match literally instead of acting as wildcards — otherwise a value of
|
|
427
|
+
* `%` matches every row (a filter-bypass, P0). Binds an explicit `ESCAPE '\'`
|
|
428
|
+
* because SQLite does not honour a default escape character (MySQL/Postgres do,
|
|
429
|
+
* but the explicit clause is correct for all three).
|
|
430
|
+
*/
|
|
431
|
+
private applyContainsLike;
|
|
422
432
|
protected applyFilterCondition(builder: Knex.QueryBuilder, condition: any, logicalOp?: 'and' | 'or', tableHint?: string | null): void;
|
|
423
433
|
protected mapSortField(field: string): string;
|
|
424
434
|
protected mapAggregateFunc(func: string): string;
|
package/dist/index.d.ts
CHANGED
|
@@ -85,6 +85,7 @@ declare class SqlDriver implements IDataDriver {
|
|
|
85
85
|
jsonFields: boolean;
|
|
86
86
|
arrayFields: boolean;
|
|
87
87
|
vectorSearch: boolean;
|
|
88
|
+
autonumber: boolean;
|
|
88
89
|
schemaSync: boolean;
|
|
89
90
|
batchSchemaSync: boolean;
|
|
90
91
|
migrations: boolean;
|
|
@@ -419,6 +420,15 @@ declare class SqlDriver implements IDataDriver {
|
|
|
419
420
|
*/
|
|
420
421
|
protected coerceFilterValue(table: string | null, field: string, value: any): any;
|
|
421
422
|
protected applyFilters(builder: Knex.QueryBuilder, filters: any): void;
|
|
423
|
+
/**
|
|
424
|
+
* Apply a `contains` substring match as a parameterized `LIKE '%…%'`, escaping
|
|
425
|
+
* the LIKE metacharacters `%` / `_` (and the escape char `\`) in the user value
|
|
426
|
+
* so they match literally instead of acting as wildcards — otherwise a value of
|
|
427
|
+
* `%` matches every row (a filter-bypass, P0). Binds an explicit `ESCAPE '\'`
|
|
428
|
+
* because SQLite does not honour a default escape character (MySQL/Postgres do,
|
|
429
|
+
* but the explicit clause is correct for all three).
|
|
430
|
+
*/
|
|
431
|
+
private applyContainsLike;
|
|
422
432
|
protected applyFilterCondition(builder: Knex.QueryBuilder, condition: any, logicalOp?: 'and' | 'or', tableHint?: string | null): void;
|
|
423
433
|
protected mapSortField(field: string): string;
|
|
424
434
|
protected mapAggregateFunc(func: string): string;
|
package/dist/index.js
CHANGED
|
@@ -139,6 +139,10 @@ var SqlDriver = class {
|
|
|
139
139
|
jsonFields: true,
|
|
140
140
|
arrayFields: true,
|
|
141
141
|
vectorSearch: false,
|
|
142
|
+
// Persistent, atomic autonumber sequences via `_objectstack_sequences`
|
|
143
|
+
// (see fillAutoNumberFields / getNextSequenceValue). The engine defers
|
|
144
|
+
// autonumber generation to this driver — it is the single source of truth.
|
|
145
|
+
autonumber: true,
|
|
142
146
|
// Schema Management
|
|
143
147
|
schemaSync: true,
|
|
144
148
|
batchSchemaSync: false,
|
|
@@ -546,7 +550,10 @@ var SqlDriver = class {
|
|
|
546
550
|
async bulkCreate(object, data, options) {
|
|
547
551
|
this.auditMissingTenant(object, "bulkCreate", options);
|
|
548
552
|
for (const row of data) {
|
|
549
|
-
if (row && typeof row === "object")
|
|
553
|
+
if (row && typeof row === "object") {
|
|
554
|
+
this.injectTenantOnInsert(object, row, options);
|
|
555
|
+
await this.fillAutoNumberFields(object, row, options);
|
|
556
|
+
}
|
|
550
557
|
}
|
|
551
558
|
const builder = this.getBuilder(object, options);
|
|
552
559
|
return await builder.insert(data).returning("*");
|
|
@@ -841,7 +848,8 @@ var SqlDriver = class {
|
|
|
841
848
|
((_b = this.datetimeFields)[tableName] ?? (_b[tableName] = /* @__PURE__ */ new Set())).add(name);
|
|
842
849
|
}
|
|
843
850
|
if (type === "auto_number" || type === "autonumber") {
|
|
844
|
-
const
|
|
851
|
+
const rawFmt = typeof field.autonumberFormat === "string" && field.autonumberFormat ? field.autonumberFormat : typeof field.format === "string" && field.format ? field.format : "";
|
|
852
|
+
const fmt = rawFmt || "{0000}";
|
|
845
853
|
const m = fmt.match(/\{(0+)\}/);
|
|
846
854
|
const padWidth = m ? m[1].length : 4;
|
|
847
855
|
const prefix = m ? fmt.slice(0, m.index ?? 0) : fmt;
|
|
@@ -1229,7 +1237,7 @@ var SqlDriver = class {
|
|
|
1229
1237
|
const methodIn = nextJoin === "or" ? "orWhereIn" : "whereIn";
|
|
1230
1238
|
const methodNotIn = nextJoin === "or" ? "orWhereNotIn" : "whereNotIn";
|
|
1231
1239
|
if (op === "contains") {
|
|
1232
|
-
b
|
|
1240
|
+
this.applyContainsLike(b, method, field, value);
|
|
1233
1241
|
return;
|
|
1234
1242
|
}
|
|
1235
1243
|
switch (op) {
|
|
@@ -1260,6 +1268,19 @@ var SqlDriver = class {
|
|
|
1260
1268
|
}
|
|
1261
1269
|
}
|
|
1262
1270
|
}
|
|
1271
|
+
/**
|
|
1272
|
+
* Apply a `contains` substring match as a parameterized `LIKE '%…%'`, escaping
|
|
1273
|
+
* the LIKE metacharacters `%` / `_` (and the escape char `\`) in the user value
|
|
1274
|
+
* so they match literally instead of acting as wildcards — otherwise a value of
|
|
1275
|
+
* `%` matches every row (a filter-bypass, P0). Binds an explicit `ESCAPE '\'`
|
|
1276
|
+
* because SQLite does not honour a default escape character (MySQL/Postgres do,
|
|
1277
|
+
* but the explicit clause is correct for all three).
|
|
1278
|
+
*/
|
|
1279
|
+
applyContainsLike(builder, method, field, value) {
|
|
1280
|
+
const escaped = String(value).replace(/[\\%_]/g, "\\$&");
|
|
1281
|
+
const rawMethod = method.startsWith("or") ? "orWhereRaw" : "whereRaw";
|
|
1282
|
+
builder[rawMethod]("?? LIKE ? ESCAPE ?", [field, `%${escaped}%`, "\\"]);
|
|
1283
|
+
}
|
|
1263
1284
|
applyFilterCondition(builder, condition, logicalOp = "and", tableHint) {
|
|
1264
1285
|
if (!condition || typeof condition !== "object") return;
|
|
1265
1286
|
const table = tableHint ?? this.tableNameForBuilder(builder);
|
|
@@ -1316,7 +1337,7 @@ var SqlDriver = class {
|
|
|
1316
1337
|
break;
|
|
1317
1338
|
}
|
|
1318
1339
|
case "$contains":
|
|
1319
|
-
builder
|
|
1340
|
+
this.applyContainsLike(builder, method, field, opValue);
|
|
1320
1341
|
break;
|
|
1321
1342
|
default:
|
|
1322
1343
|
builder[method](field, coerced);
|