sqlite-zod-orm 3.21.0 → 3.23.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.js +21 -0
- package/package.json +1 -1
- package/src/builder.ts +54 -0
package/dist/index.js
CHANGED
|
@@ -4493,6 +4493,12 @@ class QueryBuilder {
|
|
|
4493
4493
|
first() {
|
|
4494
4494
|
return this.get();
|
|
4495
4495
|
}
|
|
4496
|
+
firstOrFail() {
|
|
4497
|
+
const row = this.get();
|
|
4498
|
+
if (row === null)
|
|
4499
|
+
throw new Error("No matching row found");
|
|
4500
|
+
return row;
|
|
4501
|
+
}
|
|
4496
4502
|
exists() {
|
|
4497
4503
|
const { sql: selectSql, params } = compileIQO(this.tableName, this.iqo);
|
|
4498
4504
|
const existsSql = selectSql.replace(/^SELECT .+? FROM/, "SELECT 1 FROM").replace(/ LIMIT \d+/, "") + " LIMIT 1";
|
|
@@ -4572,6 +4578,9 @@ class QueryBuilder {
|
|
|
4572
4578
|
const aggSql = selectSql.replace(/^SELECT .+? FROM/, `SELECT ${groupCols}, COUNT(*) as count FROM`);
|
|
4573
4579
|
return this.executor(aggSql, params, true);
|
|
4574
4580
|
}
|
|
4581
|
+
toSQL() {
|
|
4582
|
+
return compileIQO(this.tableName, this.iqo);
|
|
4583
|
+
}
|
|
4575
4584
|
pluck(column) {
|
|
4576
4585
|
const { sql: selectSql, params } = compileIQO(this.tableName, this.iqo);
|
|
4577
4586
|
const pluckSql = selectSql.replace(/^SELECT .+? FROM/, `SELECT "${column}" FROM`);
|
|
@@ -4611,6 +4620,18 @@ class QueryBuilder {
|
|
|
4611
4620
|
const result = this.executor(`SELECT changes() as c`, [], true);
|
|
4612
4621
|
return result[0]?.c ?? 0;
|
|
4613
4622
|
}
|
|
4623
|
+
increment(column, amount = 1) {
|
|
4624
|
+
const { sql: selectSql, params } = compileIQO(this.tableName, this.iqo);
|
|
4625
|
+
const whereMatch = selectSql.match(/WHERE (.+?)(?:\s+ORDER|\s+LIMIT|\s+GROUP|\s+HAVING|$)/s);
|
|
4626
|
+
const wherePart = whereMatch ? whereMatch[1] : "1=1";
|
|
4627
|
+
const sql = `UPDATE "${this.tableName}" SET "${column}" = "${column}" + ? WHERE ${wherePart}`;
|
|
4628
|
+
this.executor(sql, [amount, ...params], true);
|
|
4629
|
+
const result = this.executor(`SELECT changes() as c`, [], true);
|
|
4630
|
+
return result[0]?.c ?? 0;
|
|
4631
|
+
}
|
|
4632
|
+
decrement(column, amount = 1) {
|
|
4633
|
+
return this.increment(column, -amount);
|
|
4634
|
+
}
|
|
4614
4635
|
then(onfulfilled, onrejected) {
|
|
4615
4636
|
try {
|
|
4616
4637
|
const result = this.all();
|
package/package.json
CHANGED
package/src/builder.ts
CHANGED
|
@@ -330,6 +330,19 @@ export class QueryBuilder<T extends Record<string, any>, TResult extends Record<
|
|
|
330
330
|
return this.get();
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
+
/**
|
|
334
|
+
* Return the first matching row or throw if none found.
|
|
335
|
+
* ```ts
|
|
336
|
+
* const user = db.users.select().where({ id: 1 }).firstOrFail();
|
|
337
|
+
* // throws Error('No matching row found') if id=1 doesn't exist
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
340
|
+
firstOrFail(): TResult {
|
|
341
|
+
const row = this.get();
|
|
342
|
+
if (row === null) throw new Error('No matching row found');
|
|
343
|
+
return row;
|
|
344
|
+
}
|
|
345
|
+
|
|
333
346
|
/** Returns true if at least one row matches the query. */
|
|
334
347
|
exists(): boolean {
|
|
335
348
|
const { sql: selectSql, params } = compileIQO(this.tableName, this.iqo);
|
|
@@ -465,6 +478,19 @@ export class QueryBuilder<T extends Record<string, any>, TResult extends Record<
|
|
|
465
478
|
return this.executor(aggSql, params, true) as any;
|
|
466
479
|
}
|
|
467
480
|
|
|
481
|
+
// ---------- Query Inspection ----------
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Compile and return the SQL string + params without executing.
|
|
485
|
+
* ```ts
|
|
486
|
+
* db.users.select().where({ role: 'admin' }).toSQL()
|
|
487
|
+
* // → { sql: 'SELECT * FROM "users" WHERE "role" = ?', params: ['admin'] }
|
|
488
|
+
* ```
|
|
489
|
+
*/
|
|
490
|
+
toSQL(): { sql: string; params: any[] } {
|
|
491
|
+
return compileIQO(this.tableName, this.iqo);
|
|
492
|
+
}
|
|
493
|
+
|
|
468
494
|
// ---------- Convenience Methods ----------
|
|
469
495
|
|
|
470
496
|
/**
|
|
@@ -546,6 +572,34 @@ export class QueryBuilder<T extends Record<string, any>, TResult extends Record<
|
|
|
546
572
|
return (result[0] as any)?.c ?? 0;
|
|
547
573
|
}
|
|
548
574
|
|
|
575
|
+
/**
|
|
576
|
+
* Atomically increment a numeric column for matching rows.
|
|
577
|
+
* Returns the number of affected rows.
|
|
578
|
+
* ```ts
|
|
579
|
+
* db.users.select().where({ id: 1 }).increment('score', 10)
|
|
580
|
+
* ```
|
|
581
|
+
*/
|
|
582
|
+
increment(column: keyof T & string, amount: number = 1): number {
|
|
583
|
+
const { sql: selectSql, params } = compileIQO(this.tableName, this.iqo);
|
|
584
|
+
const whereMatch = selectSql.match(/WHERE (.+?)(?:\s+ORDER|\s+LIMIT|\s+GROUP|\s+HAVING|$)/s);
|
|
585
|
+
const wherePart = whereMatch ? whereMatch[1] : '1=1';
|
|
586
|
+
|
|
587
|
+
const sql = `UPDATE "${this.tableName}" SET "${column}" = "${column}" + ? WHERE ${wherePart}`;
|
|
588
|
+
this.executor(sql, [amount, ...params], true);
|
|
589
|
+
const result = this.executor(`SELECT changes() as c`, [], true);
|
|
590
|
+
return (result[0] as any)?.c ?? 0;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Atomically decrement a numeric column for matching rows.
|
|
595
|
+
* Returns the number of affected rows.
|
|
596
|
+
* ```ts
|
|
597
|
+
* db.users.select().where({ id: 1 }).decrement('score', 5)
|
|
598
|
+
* ```
|
|
599
|
+
*/
|
|
600
|
+
decrement(column: keyof T & string, amount: number = 1): number {
|
|
601
|
+
return this.increment(column, -amount);
|
|
602
|
+
}
|
|
549
603
|
|
|
550
604
|
// ---------- Thenable (async/await support) ----------
|
|
551
605
|
|