@bunnykit/orm 0.1.15 → 0.1.17
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/src/connection/Connection.d.ts +2 -2
- package/dist/src/connection/Connection.js +5 -5
- package/dist/src/query/Builder.d.ts +3 -1
- package/dist/src/query/Builder.js +102 -48
- package/dist/src/query/grammars/Grammar.d.ts +1 -0
- package/dist/src/query/grammars/MySqlGrammar.d.ts +1 -0
- package/dist/src/query/grammars/MySqlGrammar.js +3 -0
- package/dist/src/query/grammars/PostgresGrammar.d.ts +1 -0
- package/dist/src/query/grammars/PostgresGrammar.js +3 -0
- package/dist/src/query/grammars/SQLiteGrammar.d.ts +1 -0
- package/dist/src/query/grammars/SQLiteGrammar.js +3 -0
- package/dist/src/types/index.d.ts +4 -1
- package/package.json +1 -1
|
@@ -20,8 +20,8 @@ export declare class Connection {
|
|
|
20
20
|
withoutSchema(): Connection;
|
|
21
21
|
qualifyTable(table: string): string;
|
|
22
22
|
private quoteIdentifier;
|
|
23
|
-
query(sqlString: string): Promise<any[]>;
|
|
24
|
-
run(sqlString: string): Promise<any>;
|
|
23
|
+
query(sqlString: string, bindings?: any[]): Promise<any[]>;
|
|
24
|
+
run(sqlString: string, bindings?: any[]): Promise<any>;
|
|
25
25
|
beginTransaction(): Promise<void>;
|
|
26
26
|
commit(): Promise<void>;
|
|
27
27
|
rollback(): Promise<void>;
|
|
@@ -75,11 +75,11 @@ export class Connection {
|
|
|
75
75
|
quoteIdentifier(value) {
|
|
76
76
|
return `"${value.replace(/"/g, '""')}"`;
|
|
77
77
|
}
|
|
78
|
-
async query(sqlString) {
|
|
79
|
-
return (await this.driver.unsafe(sqlString));
|
|
78
|
+
async query(sqlString, bindings) {
|
|
79
|
+
return (await this.driver.unsafe(sqlString, bindings));
|
|
80
80
|
}
|
|
81
|
-
async run(sqlString) {
|
|
82
|
-
return await this.driver.unsafe(sqlString);
|
|
81
|
+
async run(sqlString, bindings) {
|
|
82
|
+
return await this.driver.unsafe(sqlString, bindings);
|
|
83
83
|
}
|
|
84
84
|
async beginTransaction() {
|
|
85
85
|
await this.driver.unsafe("BEGIN");
|
|
@@ -105,7 +105,7 @@ export class Connection {
|
|
|
105
105
|
return await this.transaction(callback);
|
|
106
106
|
}
|
|
107
107
|
return await this.transaction(async (connection) => {
|
|
108
|
-
await connection.run(`SET LOCAL ${setting} = ${connection.getGrammar().
|
|
108
|
+
await connection.run(`SET LOCAL ${setting} = ${connection.getGrammar().placeholder(1)}`, [tenantId]);
|
|
109
109
|
return await callback(connection);
|
|
110
110
|
});
|
|
111
111
|
}
|
|
@@ -31,6 +31,7 @@ export declare class Builder<T = Record<string, any>> {
|
|
|
31
31
|
fromRaw?: string;
|
|
32
32
|
updateJoins: string[];
|
|
33
33
|
bindings: any[];
|
|
34
|
+
private parameterize;
|
|
34
35
|
constructor(connection: Connection, table: string);
|
|
35
36
|
private get grammar();
|
|
36
37
|
setModel(model: ModelConstructor): this;
|
|
@@ -130,6 +131,7 @@ export declare class Builder<T = Record<string, any>> {
|
|
|
130
131
|
clone(): Builder<T>;
|
|
131
132
|
wrapColumn(value: string): string;
|
|
132
133
|
escapeValue(value: any): string;
|
|
134
|
+
private addBinding;
|
|
133
135
|
private compileWhereClause;
|
|
134
136
|
private compileWheres;
|
|
135
137
|
private compileNestedWheres;
|
|
@@ -158,7 +160,7 @@ export declare class Builder<T = Record<string, any>> {
|
|
|
158
160
|
paginate(perPage?: number, page?: number): Promise<Paginator<T>>;
|
|
159
161
|
chunk(count: number, callback: (items: T[]) => void | Promise<void>): Promise<void>;
|
|
160
162
|
each(count: number, callback: (item: T) => void | Promise<void>): Promise<void>;
|
|
161
|
-
cursor(
|
|
163
|
+
cursor(chunkSize?: number): AsyncGenerator<T>;
|
|
162
164
|
lazy(count?: number): AsyncGenerator<T>;
|
|
163
165
|
insert(data: ModelAttributeInput<T> | ModelAttributeInput<T>[]): Promise<any>;
|
|
164
166
|
insertGetId(data: ModelAttributeInput<T>, idColumn?: ModelColumn<T>): Promise<any>;
|
|
@@ -19,6 +19,7 @@ export class Builder {
|
|
|
19
19
|
fromRaw;
|
|
20
20
|
updateJoins = [];
|
|
21
21
|
bindings = [];
|
|
22
|
+
parameterize = false;
|
|
22
23
|
constructor(connection, table) {
|
|
23
24
|
this.connection = connection;
|
|
24
25
|
this.tableName = table;
|
|
@@ -258,11 +259,11 @@ export class Builder {
|
|
|
258
259
|
return this;
|
|
259
260
|
}
|
|
260
261
|
having(column, operator, value) {
|
|
261
|
-
this.havings.push({
|
|
262
|
+
this.havings.push({ column, operator, value, boolean: "and" });
|
|
262
263
|
return this;
|
|
263
264
|
}
|
|
264
265
|
orHaving(column, operator, value) {
|
|
265
|
-
this.havings.push({
|
|
266
|
+
this.havings.push({ column, operator, value, boolean: "or" });
|
|
266
267
|
return this;
|
|
267
268
|
}
|
|
268
269
|
havingRaw(sql, boolean = "and") {
|
|
@@ -465,13 +466,21 @@ export class Builder {
|
|
|
465
466
|
escapeValue(value) {
|
|
466
467
|
return this.grammar.escape(value);
|
|
467
468
|
}
|
|
469
|
+
addBinding(value) {
|
|
470
|
+
this.bindings.push(value);
|
|
471
|
+
return this.grammar.placeholder(this.bindings.length);
|
|
472
|
+
}
|
|
468
473
|
compileWhereClause(where, prefix) {
|
|
469
474
|
if (where.type === "basic") {
|
|
470
|
-
|
|
475
|
+
const value = this.parameterize ? this.addBinding(where.value) : this.grammar.escape(where.value);
|
|
476
|
+
return `${prefix} ${this.grammar.wrap(where.column)} ${where.operator} ${value}`;
|
|
471
477
|
}
|
|
472
478
|
else if (where.type === "in") {
|
|
473
479
|
const op = where.operator === "NOT IN" ? "NOT IN" : "IN";
|
|
474
|
-
|
|
480
|
+
const values = this.parameterize
|
|
481
|
+
? where.value.map((v) => this.addBinding(v)).join(", ")
|
|
482
|
+
: where.value.map((v) => this.grammar.escape(v)).join(", ");
|
|
483
|
+
return `${prefix} ${this.grammar.wrap(where.column)} ${op} (${values})`;
|
|
475
484
|
}
|
|
476
485
|
else if (where.type === "null") {
|
|
477
486
|
const op = where.operator === "NOT NULL" ? "IS NOT NULL" : "IS NULL";
|
|
@@ -479,7 +488,9 @@ export class Builder {
|
|
|
479
488
|
}
|
|
480
489
|
else if (where.type === "between") {
|
|
481
490
|
const op = where.operator === "NOT BETWEEN" ? "NOT BETWEEN" : "BETWEEN";
|
|
482
|
-
|
|
491
|
+
const low = this.parameterize ? this.addBinding(where.value[0]) : this.grammar.escape(where.value[0]);
|
|
492
|
+
const high = this.parameterize ? this.addBinding(where.value[1]) : this.grammar.escape(where.value[1]);
|
|
493
|
+
return `${prefix} ${this.grammar.wrap(where.column)} ${op} ${low} AND ${high}`;
|
|
483
494
|
}
|
|
484
495
|
else if (where.type === "raw") {
|
|
485
496
|
return `${prefix} ${where.column}`;
|
|
@@ -528,7 +539,11 @@ export class Builder {
|
|
|
528
539
|
return "";
|
|
529
540
|
const clauses = this.havings.map((h, index) => {
|
|
530
541
|
const prefix = index === 0 ? "" : h.boolean.toUpperCase() + " ";
|
|
531
|
-
|
|
542
|
+
if (h.sql) {
|
|
543
|
+
return prefix + h.sql;
|
|
544
|
+
}
|
|
545
|
+
const value = this.parameterize ? this.addBinding(h.value) : this.grammar.escape(h.value);
|
|
546
|
+
return prefix + `${this.grammar.wrap(h.column)} ${h.operator} ${value}`;
|
|
532
547
|
});
|
|
533
548
|
return `HAVING ${clauses.join(" ")}`;
|
|
534
549
|
}
|
|
@@ -567,7 +582,11 @@ export class Builder {
|
|
|
567
582
|
return sql.replace(/\s+/g, " ").trim();
|
|
568
583
|
}
|
|
569
584
|
async get() {
|
|
570
|
-
|
|
585
|
+
this.bindings = [];
|
|
586
|
+
this.parameterize = true;
|
|
587
|
+
const sql = this.toSql();
|
|
588
|
+
this.parameterize = false;
|
|
589
|
+
const results = await this.connection.query(sql, this.bindings);
|
|
571
590
|
const rows = Array.from(results);
|
|
572
591
|
if (this.model) {
|
|
573
592
|
const models = rows.map((row) => {
|
|
@@ -699,34 +718,40 @@ export class Builder {
|
|
|
699
718
|
}
|
|
700
719
|
});
|
|
701
720
|
}
|
|
702
|
-
async *cursor(
|
|
721
|
+
async *cursor(chunkSize = 1000) {
|
|
703
722
|
const model = this.model;
|
|
704
723
|
const primaryKey = model ? model.primaryKey || "id" : "id";
|
|
705
724
|
const orderColumn = this.orders[0]?.column || primaryKey;
|
|
706
725
|
const orderDirection = this.orders[0]?.direction || "asc";
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
builder.
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
726
|
+
let lastValue = undefined;
|
|
727
|
+
while (true) {
|
|
728
|
+
const builder = this.clone();
|
|
729
|
+
builder.orders = [{ column: orderColumn, direction: orderDirection }];
|
|
730
|
+
builder.offsetValue = undefined;
|
|
731
|
+
builder.limitValue = chunkSize;
|
|
732
|
+
if (lastValue !== undefined) {
|
|
733
|
+
const op = orderDirection === "asc" ? ">" : "<";
|
|
734
|
+
builder.wheres.push({
|
|
735
|
+
type: "basic",
|
|
736
|
+
column: orderColumn,
|
|
737
|
+
operator: op,
|
|
738
|
+
value: lastValue,
|
|
739
|
+
boolean: "and",
|
|
740
|
+
scope: undefined,
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
const items = await builder.get();
|
|
744
|
+
if (items.length === 0)
|
|
745
|
+
break;
|
|
746
|
+
for (const item of items) {
|
|
747
|
+
yield item;
|
|
748
|
+
}
|
|
749
|
+
if (items.length < chunkSize)
|
|
750
|
+
break;
|
|
751
|
+
const lastItem = items[items.length - 1];
|
|
752
|
+
lastValue = lastItem && typeof lastItem === "object"
|
|
753
|
+
? lastItem[orderColumn]
|
|
754
|
+
: undefined;
|
|
730
755
|
}
|
|
731
756
|
}
|
|
732
757
|
async *lazy(count = 1000) {
|
|
@@ -748,11 +773,15 @@ export class Builder {
|
|
|
748
773
|
if (records.length === 0)
|
|
749
774
|
return;
|
|
750
775
|
const columns = Object.keys(records[0]);
|
|
776
|
+
const bindings = [];
|
|
751
777
|
const values = records.map((record) => {
|
|
752
|
-
return `(${columns.map((col) =>
|
|
778
|
+
return `(${columns.map((col) => {
|
|
779
|
+
bindings.push(record[col]);
|
|
780
|
+
return this.grammar.placeholder(bindings.length);
|
|
781
|
+
}).join(", ")})`;
|
|
753
782
|
});
|
|
754
783
|
const sql = `INSERT INTO ${this.grammar.wrap(this.tableName)} (${columns.map((c) => this.grammar.wrap(c)).join(", ")}) VALUES ${values.join(", ")}`;
|
|
755
|
-
return await this.connection.run(sql);
|
|
784
|
+
return await this.connection.run(sql, bindings);
|
|
756
785
|
}
|
|
757
786
|
async insertGetId(data, idColumn = "id") {
|
|
758
787
|
const result = await this.insert(data);
|
|
@@ -763,43 +792,65 @@ export class Builder {
|
|
|
763
792
|
if (records.length === 0)
|
|
764
793
|
return;
|
|
765
794
|
const columns = Object.keys(records[0]);
|
|
795
|
+
const bindings = [];
|
|
766
796
|
const values = records.map((record) => {
|
|
767
|
-
return `(${columns.map((col) =>
|
|
797
|
+
return `(${columns.map((col) => {
|
|
798
|
+
bindings.push(record[col]);
|
|
799
|
+
return this.grammar.placeholder(bindings.length);
|
|
800
|
+
}).join(", ")})`;
|
|
768
801
|
});
|
|
769
802
|
const sql = this.grammar.compileInsertOrIgnore(this.grammar.wrap(this.tableName), columns, values);
|
|
770
|
-
return await this.connection.run(sql);
|
|
803
|
+
return await this.connection.run(sql, bindings);
|
|
771
804
|
}
|
|
772
805
|
async upsert(data, uniqueBy, updateColumns) {
|
|
773
806
|
const records = Array.isArray(data) ? data : [data];
|
|
774
807
|
if (records.length === 0)
|
|
775
808
|
return;
|
|
776
809
|
const columns = Object.keys(records[0]);
|
|
810
|
+
const bindings = [];
|
|
777
811
|
const values = records.map((record) => {
|
|
778
|
-
return `(${columns.map((col) =>
|
|
812
|
+
return `(${columns.map((col) => {
|
|
813
|
+
bindings.push(record[col]);
|
|
814
|
+
return this.grammar.placeholder(bindings.length);
|
|
815
|
+
}).join(", ")})`;
|
|
779
816
|
});
|
|
780
817
|
const uniqueCols = Array.isArray(uniqueBy) ? uniqueBy : [uniqueBy];
|
|
781
818
|
const updateCols = updateColumns ?? columns.filter((c) => !uniqueCols.includes(c));
|
|
782
819
|
const sql = this.grammar.compileUpsert(this.grammar.wrap(this.tableName), columns, values, uniqueCols, updateCols);
|
|
783
|
-
return await this.connection.run(sql);
|
|
820
|
+
return await this.connection.run(sql, bindings);
|
|
784
821
|
}
|
|
785
822
|
async update(data) {
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
823
|
+
this.bindings = [];
|
|
824
|
+
this.parameterize = true;
|
|
825
|
+
const sets = Object.entries(data).map(([key, value]) => {
|
|
826
|
+
this.bindings.push(value);
|
|
827
|
+
return `${this.grammar.wrap(key)} = ${this.grammar.placeholder(this.bindings.length)}`;
|
|
828
|
+
});
|
|
829
|
+
const whereSql = this.compileWheres();
|
|
830
|
+
this.parameterize = false;
|
|
831
|
+
const sql = this.grammar.compileUpdate(this.grammar.wrap(this.tableName), sets, whereSql, this.updateJoins);
|
|
832
|
+
return await this.connection.run(sql, this.bindings);
|
|
791
833
|
}
|
|
792
834
|
async delete() {
|
|
793
|
-
|
|
794
|
-
|
|
835
|
+
this.bindings = [];
|
|
836
|
+
this.parameterize = true;
|
|
837
|
+
const whereSql = this.compileWheres();
|
|
838
|
+
this.parameterize = false;
|
|
839
|
+
const sql = this.grammar.compileDelete(this.grammar.wrap(this.tableName), whereSql, this.updateJoins, this.limitValue);
|
|
840
|
+
return await this.connection.run(sql, this.bindings);
|
|
795
841
|
}
|
|
796
842
|
async increment(column, amount = 1, extra = {}) {
|
|
843
|
+
this.bindings = [];
|
|
844
|
+
this.parameterize = true;
|
|
797
845
|
const sets = [`${this.grammar.wrap(column)} = ${this.grammar.wrap(column)} + ${amount}`];
|
|
798
846
|
for (const [key, value] of Object.entries(extra)) {
|
|
799
|
-
|
|
847
|
+
this.bindings.push(value);
|
|
848
|
+
sets.push(`${this.grammar.wrap(key)} = ${this.grammar.placeholder(this.bindings.length)}`);
|
|
800
849
|
}
|
|
801
|
-
const
|
|
802
|
-
|
|
850
|
+
const whereSql = this.compileWheres();
|
|
851
|
+
this.parameterize = false;
|
|
852
|
+
const sql = `UPDATE ${this.grammar.wrap(this.tableName)} SET ${sets.join(", ")} ${whereSql}`;
|
|
853
|
+
return await this.connection.run(sql.trim(), this.bindings);
|
|
803
854
|
}
|
|
804
855
|
async decrement(column, amount = 1, extra = {}) {
|
|
805
856
|
return this.increment(column, -amount, extra);
|
|
@@ -841,8 +892,11 @@ export class Builder {
|
|
|
841
892
|
throw new Error("dd() called — execution halted.");
|
|
842
893
|
}
|
|
843
894
|
async explain() {
|
|
895
|
+
this.bindings = [];
|
|
896
|
+
this.parameterize = true;
|
|
844
897
|
const sql = this.grammar.compileExplain(this.toSql());
|
|
845
|
-
|
|
898
|
+
this.parameterize = false;
|
|
899
|
+
const results = await this.connection.query(sql, this.bindings);
|
|
846
900
|
return Array.from(results);
|
|
847
901
|
}
|
|
848
902
|
take(count) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare abstract class Grammar {
|
|
2
2
|
abstract wrap(value: string): string;
|
|
3
3
|
wrapArray(values: string[]): string[];
|
|
4
|
+
abstract placeholder(index: number): string;
|
|
4
5
|
escape(value: any): string;
|
|
5
6
|
abstract compileRandomOrder(): string;
|
|
6
7
|
compileOffset(offset: number, _limit?: number): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Grammar } from "./Grammar.js";
|
|
2
2
|
export declare class MySqlGrammar extends Grammar {
|
|
3
3
|
wrap(value: string): string;
|
|
4
|
+
placeholder(_index: number): string;
|
|
4
5
|
compileRandomOrder(): string;
|
|
5
6
|
compileDateWhere(type: string, column: string, operator: string, value: any): string;
|
|
6
7
|
compileInsertOrIgnore(table: string, columns: string[], values: string[]): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Grammar } from "./Grammar.js";
|
|
2
2
|
export declare class PostgresGrammar extends Grammar {
|
|
3
3
|
wrap(value: string): string;
|
|
4
|
+
placeholder(index: number): string;
|
|
4
5
|
compileRandomOrder(): string;
|
|
5
6
|
compileDateWhere(type: string, column: string, operator: string, value: any): string;
|
|
6
7
|
compileInsertOrIgnore(table: string, columns: string[], values: string[]): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Grammar } from "./Grammar.js";
|
|
2
2
|
export declare class SQLiteGrammar extends Grammar {
|
|
3
3
|
wrap(value: string): string;
|
|
4
|
+
placeholder(_index: number): string;
|
|
4
5
|
compileRandomOrder(): string;
|
|
5
6
|
compileOffset(offset: number, limit?: number): string;
|
|
6
7
|
compileDateWhere(type: string, column: string, operator: string, value: any): string;
|
|
@@ -41,7 +41,10 @@ export interface OrderClause {
|
|
|
41
41
|
direction: "asc" | "desc";
|
|
42
42
|
}
|
|
43
43
|
export interface HavingClause {
|
|
44
|
-
|
|
44
|
+
column?: string;
|
|
45
|
+
operator?: string;
|
|
46
|
+
value?: any;
|
|
47
|
+
sql?: string;
|
|
45
48
|
boolean: "and" | "or";
|
|
46
49
|
}
|
|
47
50
|
export interface UnionClause {
|
package/package.json
CHANGED