bettersqlkeza 1.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/LICENSE +21 -0
- package/README.md +115 -0
- package/dist/bettersql.d.ts +107 -0
- package/dist/bettersql.d.ts.map +1 -0
- package/dist/bettersql.js +181 -0
- package/dist/bettersql.js.map +1 -0
- package/dist/delete-builder.d.ts +58 -0
- package/dist/delete-builder.d.ts.map +1 -0
- package/dist/delete-builder.js +129 -0
- package/dist/delete-builder.js.map +1 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/insert-builder.d.ts +62 -0
- package/dist/insert-builder.d.ts.map +1 -0
- package/dist/insert-builder.js +136 -0
- package/dist/insert-builder.js.map +1 -0
- package/dist/model.d.ts +185 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +404 -0
- package/dist/model.js.map +1 -0
- package/dist/query-builder.d.ts +140 -0
- package/dist/query-builder.d.ts.map +1 -0
- package/dist/query-builder.js +298 -0
- package/dist/query-builder.js.map +1 -0
- package/dist/raw-query-builder.d.ts +70 -0
- package/dist/raw-query-builder.d.ts.map +1 -0
- package/dist/raw-query-builder.js +118 -0
- package/dist/raw-query-builder.js.map +1 -0
- package/dist/result-proxy.d.ts +63 -0
- package/dist/result-proxy.d.ts.map +1 -0
- package/dist/result-proxy.js +166 -0
- package/dist/result-proxy.js.map +1 -0
- package/dist/types.d.ts +87 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/update-builder.d.ts +59 -0
- package/dist/update-builder.d.ts.map +1 -0
- package/dist/update-builder.js +136 -0
- package/dist/update-builder.js.map +1 -0
- package/dist/where-builder.d.ts +18 -0
- package/dist/where-builder.d.ts.map +1 -0
- package/dist/where-builder.js +117 -0
- package/dist/where-builder.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QueryBuilder = void 0;
|
|
4
|
+
const where_builder_1 = require("./where-builder");
|
|
5
|
+
const result_proxy_1 = require("./result-proxy");
|
|
6
|
+
/**
|
|
7
|
+
* QueryBuilder<T> - A fluent query builder for constructing SQL queries
|
|
8
|
+
* Queries are only executed when .all(), .first(), or .run() are called
|
|
9
|
+
*/
|
|
10
|
+
class QueryBuilder {
|
|
11
|
+
db;
|
|
12
|
+
tableName;
|
|
13
|
+
_where = {};
|
|
14
|
+
_orConditions = [];
|
|
15
|
+
_orderBy = [];
|
|
16
|
+
_limit;
|
|
17
|
+
_offset;
|
|
18
|
+
_select = ['*'];
|
|
19
|
+
_distinct = false;
|
|
20
|
+
_groupBy = [];
|
|
21
|
+
_having = {};
|
|
22
|
+
statementCache;
|
|
23
|
+
primaryKey;
|
|
24
|
+
constructor(db, tableName, statementCache, initialWhere, primaryKey) {
|
|
25
|
+
this.db = db;
|
|
26
|
+
this.tableName = tableName;
|
|
27
|
+
this.statementCache = statementCache;
|
|
28
|
+
this.primaryKey = primaryKey ?? null;
|
|
29
|
+
if (initialWhere) {
|
|
30
|
+
this._where = { ...initialWhere };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
where(conditionsOrColumn, operator, value) {
|
|
34
|
+
if (typeof conditionsOrColumn === 'string' && operator !== undefined && value !== undefined) {
|
|
35
|
+
// Called as where(column, operator, value)
|
|
36
|
+
const condition = (0, where_builder_1.operatorToCondition)(operator, value);
|
|
37
|
+
this._where = { ...this._where, [conditionsOrColumn]: condition };
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Called as where(conditions)
|
|
41
|
+
this._where = { ...this._where, ...conditionsOrColumn };
|
|
42
|
+
}
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
orWhere(conditionsOrColumn, operator, value) {
|
|
46
|
+
if (typeof conditionsOrColumn === 'string' && operator !== undefined && value !== undefined) {
|
|
47
|
+
// Called as orWhere(column, operator, value)
|
|
48
|
+
const condition = (0, where_builder_1.operatorToCondition)(operator, value);
|
|
49
|
+
this._orConditions.push({ [conditionsOrColumn]: condition });
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Called as orWhere(conditions)
|
|
53
|
+
this._orConditions.push(conditionsOrColumn);
|
|
54
|
+
}
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Add ORDER BY clause to the query
|
|
59
|
+
*/
|
|
60
|
+
orderBy(column, direction = 'ASC') {
|
|
61
|
+
this._orderBy.push({ column, direction });
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Set LIMIT for the query
|
|
66
|
+
*/
|
|
67
|
+
limit(count) {
|
|
68
|
+
this._limit = count;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Set OFFSET for the query
|
|
73
|
+
*/
|
|
74
|
+
offset(count) {
|
|
75
|
+
this._offset = count;
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Select specific columns
|
|
80
|
+
*/
|
|
81
|
+
select(...columns) {
|
|
82
|
+
this._select = columns;
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Select DISTINCT rows
|
|
87
|
+
*/
|
|
88
|
+
distinct() {
|
|
89
|
+
this._distinct = true;
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Add GROUP BY clause
|
|
94
|
+
*/
|
|
95
|
+
groupBy(...columns) {
|
|
96
|
+
this._groupBy = columns;
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Add HAVING clause (for use with GROUP BY)
|
|
101
|
+
*/
|
|
102
|
+
having(conditions) {
|
|
103
|
+
this._having = { ...this._having, ...conditions };
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Build the SQL query and parameters
|
|
108
|
+
*/
|
|
109
|
+
buildQuery() {
|
|
110
|
+
const params = [];
|
|
111
|
+
const selectClause = this._distinct ? 'SELECT DISTINCT' : 'SELECT';
|
|
112
|
+
let sql = `${selectClause} ${this._select.join(', ')} FROM "${this.tableName}"`;
|
|
113
|
+
// WHERE clause
|
|
114
|
+
const whereClause = (0, where_builder_1.buildWhereClause)(this._where, params);
|
|
115
|
+
const orClauses = this._orConditions.map((orCond) => {
|
|
116
|
+
const orParams = [];
|
|
117
|
+
const clause = (0, where_builder_1.buildWhereClause)(orCond, orParams);
|
|
118
|
+
params.push(...orParams);
|
|
119
|
+
return `(${clause})`;
|
|
120
|
+
});
|
|
121
|
+
if (whereClause || orClauses.length > 0) {
|
|
122
|
+
if (whereClause && orClauses.length > 0) {
|
|
123
|
+
// Combine AND conditions with OR conditions: (AND conditions) OR (OR condition 1) OR (OR condition 2)
|
|
124
|
+
sql += ` WHERE (${whereClause}) OR ${orClauses.join(' OR ')}`;
|
|
125
|
+
}
|
|
126
|
+
else if (orClauses.length > 0) {
|
|
127
|
+
sql += ` WHERE ${orClauses.join(' OR ')}`;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
sql += ` WHERE ${whereClause}`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// GROUP BY clause
|
|
134
|
+
if (this._groupBy.length > 0) {
|
|
135
|
+
const groupCols = this._groupBy.map((c) => `"${String(c)}"`);
|
|
136
|
+
sql += ` GROUP BY ${groupCols.join(', ')}`;
|
|
137
|
+
}
|
|
138
|
+
// HAVING clause
|
|
139
|
+
const havingClause = (0, where_builder_1.buildWhereClause)(this._having, params);
|
|
140
|
+
if (havingClause) {
|
|
141
|
+
sql += ` HAVING ${havingClause}`;
|
|
142
|
+
}
|
|
143
|
+
// ORDER BY clause
|
|
144
|
+
if (this._orderBy.length > 0) {
|
|
145
|
+
const orderClauses = this._orderBy.map((o) => `"${String(o.column)}" ${o.direction || 'ASC'}`);
|
|
146
|
+
sql += ` ORDER BY ${orderClauses.join(', ')}`;
|
|
147
|
+
}
|
|
148
|
+
// LIMIT clause
|
|
149
|
+
if (this._limit !== undefined) {
|
|
150
|
+
sql += ` LIMIT ${this._limit}`;
|
|
151
|
+
}
|
|
152
|
+
// OFFSET clause
|
|
153
|
+
if (this._offset !== undefined) {
|
|
154
|
+
sql += ` OFFSET ${this._offset}`;
|
|
155
|
+
}
|
|
156
|
+
return { sql, params };
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get or create a cached prepared statement
|
|
160
|
+
*/
|
|
161
|
+
getStatement(sql) {
|
|
162
|
+
let stmt = this.statementCache.get(sql);
|
|
163
|
+
if (!stmt) {
|
|
164
|
+
stmt = this.db.prepare(sql);
|
|
165
|
+
this.statementCache.set(sql, stmt);
|
|
166
|
+
}
|
|
167
|
+
return stmt;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Execute query and return all matching rows
|
|
171
|
+
*/
|
|
172
|
+
all() {
|
|
173
|
+
const { sql, params } = this.buildQuery();
|
|
174
|
+
const stmt = this.getStatement(sql);
|
|
175
|
+
return stmt.all(...params);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Execute query and return the first matching row with chainable methods
|
|
179
|
+
* The result has both the data properties AND methods like delete(), update(), save()
|
|
180
|
+
* @example
|
|
181
|
+
* const user = User.query().where("id", "=", 1).first();
|
|
182
|
+
* user?.name; // Access property
|
|
183
|
+
* user?.delete(); // Delete the record
|
|
184
|
+
* user?.update({ name: "New Name" }); // Update the record
|
|
185
|
+
*/
|
|
186
|
+
first() {
|
|
187
|
+
this._limit = 1;
|
|
188
|
+
const { sql, params } = this.buildQuery();
|
|
189
|
+
const stmt = this.getStatement(sql);
|
|
190
|
+
const data = stmt.get(...params) || null;
|
|
191
|
+
return (0, result_proxy_1.createResultProxy)(this.db, this.tableName, this.statementCache, this.primaryKey, data);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Execute query and return the first matching row or throw an error
|
|
195
|
+
* The result has both the data properties AND methods like delete(), update(), save()
|
|
196
|
+
*/
|
|
197
|
+
firstOrFail() {
|
|
198
|
+
const result = this.first();
|
|
199
|
+
if (result === null) {
|
|
200
|
+
throw new Error(`No record found in table "${this.tableName}"`);
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Check if any records exist matching the query
|
|
206
|
+
*/
|
|
207
|
+
exists() {
|
|
208
|
+
const { sql, params } = this.buildQuery();
|
|
209
|
+
const existsSql = `SELECT EXISTS(${sql}) as exists_result`;
|
|
210
|
+
const stmt = this.db.prepare(existsSql);
|
|
211
|
+
const result = stmt.get(...params);
|
|
212
|
+
return result.exists_result === 1;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Get array of values for a single column
|
|
216
|
+
*/
|
|
217
|
+
pluck(column) {
|
|
218
|
+
this._select = [String(column)];
|
|
219
|
+
const results = this.all();
|
|
220
|
+
return results.map((row) => row[column]);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Execute query and return raw results (alias for all())
|
|
224
|
+
*/
|
|
225
|
+
run() {
|
|
226
|
+
return this.all();
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Execute query and return all matching rows (alias for all())
|
|
230
|
+
*/
|
|
231
|
+
get() {
|
|
232
|
+
return this.all();
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get the count of matching records
|
|
236
|
+
*/
|
|
237
|
+
count() {
|
|
238
|
+
const params = [];
|
|
239
|
+
let sql = `SELECT COUNT(*) as count FROM "${this.tableName}"`;
|
|
240
|
+
const whereClause = (0, where_builder_1.buildWhereClause)(this._where, params);
|
|
241
|
+
if (whereClause) {
|
|
242
|
+
sql += ` WHERE ${whereClause}`;
|
|
243
|
+
}
|
|
244
|
+
const stmt = this.db.prepare(sql);
|
|
245
|
+
const result = stmt.get(...params);
|
|
246
|
+
return result.count;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Get the sum of a column
|
|
250
|
+
*/
|
|
251
|
+
sum(column) {
|
|
252
|
+
return this.aggregate('SUM', column);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get the average of a column
|
|
256
|
+
*/
|
|
257
|
+
avg(column) {
|
|
258
|
+
return this.aggregate('AVG', column);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Get the minimum value of a column
|
|
262
|
+
*/
|
|
263
|
+
min(column) {
|
|
264
|
+
return this.aggregate('MIN', column);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Get the maximum value of a column
|
|
268
|
+
*/
|
|
269
|
+
max(column) {
|
|
270
|
+
return this.aggregate('MAX', column);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Execute an aggregate function
|
|
274
|
+
*/
|
|
275
|
+
aggregate(fn, column) {
|
|
276
|
+
const params = [];
|
|
277
|
+
let sql = `SELECT ${fn}("${String(column)}") as result FROM "${this.tableName}"`;
|
|
278
|
+
const whereClause = (0, where_builder_1.buildWhereClause)(this._where, params);
|
|
279
|
+
if (whereClause) {
|
|
280
|
+
sql += ` WHERE ${whereClause}`;
|
|
281
|
+
}
|
|
282
|
+
if (this._groupBy.length > 0) {
|
|
283
|
+
const groupCols = this._groupBy.map((c) => `"${String(c)}"`);
|
|
284
|
+
sql += ` GROUP BY ${groupCols.join(', ')}`;
|
|
285
|
+
}
|
|
286
|
+
const stmt = this.db.prepare(sql);
|
|
287
|
+
const result = stmt.get(...params);
|
|
288
|
+
return result.result ?? 0;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Get the SQL string for debugging
|
|
292
|
+
*/
|
|
293
|
+
toSQL() {
|
|
294
|
+
return this.buildQuery();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
exports.QueryBuilder = QueryBuilder;
|
|
298
|
+
//# sourceMappingURL=query-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-builder.js","sourceRoot":"","sources":["../src/query-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
import type { SQLQueryBindings } from './types';
|
|
3
|
+
import { ResultProxy } from './result-proxy';
|
|
4
|
+
/**
|
|
5
|
+
* RawQueryBuilder<T> - Executes raw SQL queries and returns results with chainable methods
|
|
6
|
+
* Used when passing a raw SQL string to Model.query()
|
|
7
|
+
*
|
|
8
|
+
* @warning This class executes raw SQL queries. Always use parameterized queries
|
|
9
|
+
* with the second argument to prevent SQL injection:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Safe - using parameters
|
|
12
|
+
* User.query("SELECT * FROM user WHERE id = ?", [userId])
|
|
13
|
+
*
|
|
14
|
+
* // UNSAFE - string interpolation is vulnerable to SQL injection
|
|
15
|
+
* User.query(`SELECT * FROM user WHERE id = ${userId}`) // DON'T DO THIS
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare class RawQueryBuilder<T extends Record<string, unknown>> {
|
|
19
|
+
private db;
|
|
20
|
+
private tableName;
|
|
21
|
+
private statementCache;
|
|
22
|
+
private primaryKey;
|
|
23
|
+
private rawSql;
|
|
24
|
+
private params;
|
|
25
|
+
constructor(db: Database.Database, tableName: string, statementCache: Map<string, Database.Statement>, primaryKey: string | null, rawSql: string, params?: SQLQueryBindings[]);
|
|
26
|
+
/**
|
|
27
|
+
* Get or create a cached prepared statement
|
|
28
|
+
*/
|
|
29
|
+
private getStatement;
|
|
30
|
+
/**
|
|
31
|
+
* Execute query and return all matching rows
|
|
32
|
+
*/
|
|
33
|
+
all(): T[];
|
|
34
|
+
/**
|
|
35
|
+
* Execute query and return all matching rows (alias for all())
|
|
36
|
+
*/
|
|
37
|
+
get(): T[];
|
|
38
|
+
/**
|
|
39
|
+
* Execute query and return all matching rows (alias for all())
|
|
40
|
+
*/
|
|
41
|
+
run(): T[];
|
|
42
|
+
/**
|
|
43
|
+
* Execute query and return the first matching row with chainable methods
|
|
44
|
+
*/
|
|
45
|
+
first(): (T & ResultProxy<T>) | null;
|
|
46
|
+
/**
|
|
47
|
+
* Execute query and return the first matching row or throw an error
|
|
48
|
+
*/
|
|
49
|
+
firstOrFail(): T & ResultProxy<T>;
|
|
50
|
+
/**
|
|
51
|
+
* Check if any records exist matching the query
|
|
52
|
+
*/
|
|
53
|
+
exists(): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Get the count of matching records
|
|
56
|
+
*/
|
|
57
|
+
count(): number;
|
|
58
|
+
/**
|
|
59
|
+
* Get array of values for a single column
|
|
60
|
+
*/
|
|
61
|
+
pluck<K extends keyof T>(column: K): T[K][];
|
|
62
|
+
/**
|
|
63
|
+
* Get the SQL string for debugging
|
|
64
|
+
*/
|
|
65
|
+
toSQL(): {
|
|
66
|
+
sql: string;
|
|
67
|
+
params: SQLQueryBindings[];
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=raw-query-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-query-builder.d.ts","sourceRoot":"","sources":["../src/raw-query-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,EAAqB,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE/D;;;;;;;;;;;;;GAaG;AACH,qBAAa,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5D,OAAO,CAAC,EAAE,CAAmB;IAC7B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,UAAU,CAAe;IACjC,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,MAAM,CAAoB;gBAGhC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC/C,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,gBAAgB,EAAE;IAU7B;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,GAAG,IAAI,CAAC,EAAE;IAKV;;OAEG;IACH,GAAG,IAAI,CAAC,EAAE;IAIV;;OAEG;IACH,GAAG,IAAI,CAAC,EAAE;IAIV;;OAEG;IACH,KAAK,IAAI,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAMpC;;OAEG;IACH,WAAW,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;IAUjC;;OAEG;IACH,MAAM,IAAI,OAAO;IAOjB;;OAEG;IACH,KAAK,IAAI,MAAM;IAQf;;OAEG;IACH,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;IAK3C;;OAEG;IACH,KAAK,IAAI;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,gBAAgB,EAAE,CAAA;KAAE;CAGrD"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RawQueryBuilder = void 0;
|
|
4
|
+
const result_proxy_1 = require("./result-proxy");
|
|
5
|
+
/**
|
|
6
|
+
* RawQueryBuilder<T> - Executes raw SQL queries and returns results with chainable methods
|
|
7
|
+
* Used when passing a raw SQL string to Model.query()
|
|
8
|
+
*
|
|
9
|
+
* @warning This class executes raw SQL queries. Always use parameterized queries
|
|
10
|
+
* with the second argument to prevent SQL injection:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Safe - using parameters
|
|
13
|
+
* User.query("SELECT * FROM user WHERE id = ?", [userId])
|
|
14
|
+
*
|
|
15
|
+
* // UNSAFE - string interpolation is vulnerable to SQL injection
|
|
16
|
+
* User.query(`SELECT * FROM user WHERE id = ${userId}`) // DON'T DO THIS
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
class RawQueryBuilder {
|
|
20
|
+
db;
|
|
21
|
+
tableName;
|
|
22
|
+
statementCache;
|
|
23
|
+
primaryKey;
|
|
24
|
+
rawSql;
|
|
25
|
+
params;
|
|
26
|
+
constructor(db, tableName, statementCache, primaryKey, rawSql, params) {
|
|
27
|
+
this.db = db;
|
|
28
|
+
this.tableName = tableName;
|
|
29
|
+
this.statementCache = statementCache;
|
|
30
|
+
this.primaryKey = primaryKey;
|
|
31
|
+
this.rawSql = rawSql;
|
|
32
|
+
this.params = params || [];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get or create a cached prepared statement
|
|
36
|
+
*/
|
|
37
|
+
getStatement(sql) {
|
|
38
|
+
let stmt = this.statementCache.get(sql);
|
|
39
|
+
if (!stmt) {
|
|
40
|
+
stmt = this.db.prepare(sql);
|
|
41
|
+
this.statementCache.set(sql, stmt);
|
|
42
|
+
}
|
|
43
|
+
return stmt;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Execute query and return all matching rows
|
|
47
|
+
*/
|
|
48
|
+
all() {
|
|
49
|
+
const stmt = this.getStatement(this.rawSql);
|
|
50
|
+
return stmt.all(...this.params);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Execute query and return all matching rows (alias for all())
|
|
54
|
+
*/
|
|
55
|
+
get() {
|
|
56
|
+
return this.all();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Execute query and return all matching rows (alias for all())
|
|
60
|
+
*/
|
|
61
|
+
run() {
|
|
62
|
+
return this.all();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Execute query and return the first matching row with chainable methods
|
|
66
|
+
*/
|
|
67
|
+
first() {
|
|
68
|
+
const stmt = this.getStatement(this.rawSql);
|
|
69
|
+
const data = stmt.get(...this.params) || null;
|
|
70
|
+
return (0, result_proxy_1.createResultProxy)(this.db, this.tableName, this.statementCache, this.primaryKey, data);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Execute query and return the first matching row or throw an error
|
|
74
|
+
*/
|
|
75
|
+
firstOrFail() {
|
|
76
|
+
const result = this.first();
|
|
77
|
+
if (result === null) {
|
|
78
|
+
// Truncate SQL for error message if it's too long
|
|
79
|
+
const sqlPreview = this.rawSql.length > 100 ? this.rawSql.substring(0, 100) + '...' : this.rawSql;
|
|
80
|
+
throw new Error(`No record found for query: ${sqlPreview}`);
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Check if any records exist matching the query
|
|
86
|
+
*/
|
|
87
|
+
exists() {
|
|
88
|
+
const existsSql = `SELECT EXISTS(${this.rawSql}) as exists_result`;
|
|
89
|
+
const stmt = this.db.prepare(existsSql);
|
|
90
|
+
const result = stmt.get(...this.params);
|
|
91
|
+
return result.exists_result === 1;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get the count of matching records
|
|
95
|
+
*/
|
|
96
|
+
count() {
|
|
97
|
+
// Wrap the raw SQL to get a count
|
|
98
|
+
const countSql = `SELECT COUNT(*) as count FROM (${this.rawSql})`;
|
|
99
|
+
const stmt = this.db.prepare(countSql);
|
|
100
|
+
const result = stmt.get(...this.params);
|
|
101
|
+
return result.count;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get array of values for a single column
|
|
105
|
+
*/
|
|
106
|
+
pluck(column) {
|
|
107
|
+
const results = this.all();
|
|
108
|
+
return results.map((row) => row[column]);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get the SQL string for debugging
|
|
112
|
+
*/
|
|
113
|
+
toSQL() {
|
|
114
|
+
return { sql: this.rawSql, params: this.params };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.RawQueryBuilder = RawQueryBuilder;
|
|
118
|
+
//# sourceMappingURL=raw-query-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-query-builder.js","sourceRoot":"","sources":["../src/raw-query-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
import type { UpdateData } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* ResultProxy<T> - Wraps a query result with chainable methods
|
|
5
|
+
* Allows patterns like: Model.query().where(...).first().delete()
|
|
6
|
+
* While still allowing property access: Model.query().where(...).first().propertyName
|
|
7
|
+
*/
|
|
8
|
+
export declare class ResultProxy<T extends Record<string, unknown>> {
|
|
9
|
+
private db;
|
|
10
|
+
private tableName;
|
|
11
|
+
private statementCache;
|
|
12
|
+
private primaryKey;
|
|
13
|
+
private _data;
|
|
14
|
+
constructor(db: Database.Database, tableName: string, statementCache: Map<string, Database.Statement>, primaryKey: string | null, data: T | null);
|
|
15
|
+
/**
|
|
16
|
+
* Get or create a cached prepared statement
|
|
17
|
+
*/
|
|
18
|
+
private getStatement;
|
|
19
|
+
/**
|
|
20
|
+
* Delete the current record from the database
|
|
21
|
+
* Returns the number of deleted records (0 or 1)
|
|
22
|
+
*/
|
|
23
|
+
delete(): number;
|
|
24
|
+
/**
|
|
25
|
+
* Update the current record in the database
|
|
26
|
+
* Returns the number of updated records (0 or 1)
|
|
27
|
+
*/
|
|
28
|
+
update(data: UpdateData<T>): number;
|
|
29
|
+
/**
|
|
30
|
+
* Save changes made to the record back to the database
|
|
31
|
+
* (Re-inserts/updates the full record)
|
|
32
|
+
* Returns the number of affected records
|
|
33
|
+
*/
|
|
34
|
+
save(): number;
|
|
35
|
+
/**
|
|
36
|
+
* Refresh the record from the database
|
|
37
|
+
* Returns a new result with the refreshed data and chainable methods
|
|
38
|
+
*/
|
|
39
|
+
refresh(): (T & ResultProxy<T>) | null;
|
|
40
|
+
/**
|
|
41
|
+
* Check if the record exists (is not null)
|
|
42
|
+
*/
|
|
43
|
+
exists(): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Get the underlying data
|
|
46
|
+
*/
|
|
47
|
+
toJSON(): T | null;
|
|
48
|
+
/**
|
|
49
|
+
* Get the underlying data (alias for toJSON)
|
|
50
|
+
*/
|
|
51
|
+
getData(): T | null;
|
|
52
|
+
/**
|
|
53
|
+
* Check if the result is null
|
|
54
|
+
*/
|
|
55
|
+
isNull(): boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a ResultProxy that also acts as a Proxy for direct property access
|
|
59
|
+
* This allows: result.propertyName AND result.delete()
|
|
60
|
+
* Returns null when data is null to maintain backward compatibility
|
|
61
|
+
*/
|
|
62
|
+
export declare function createResultProxy<T extends Record<string, unknown>>(db: Database.Database, tableName: string, statementCache: Map<string, Database.Statement>, primaryKey: string | null, data: T | null): (T & ResultProxy<T>) | null;
|
|
63
|
+
//# sourceMappingURL=result-proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-proxy.d.ts","sourceRoot":"","sources":["../src/result-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAoB,UAAU,EAAE,MAAM,SAAS,CAAA;AAE3D;;;;GAIG;AACH,qBAAa,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxD,OAAO,CAAC,EAAE,CAAmB;IAC7B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,UAAU,CAAe;IACjC,OAAO,CAAC,KAAK,CAAU;gBAGrB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC/C,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,IAAI,EAAE,CAAC,GAAG,IAAI;IAShB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;;OAGG;IACH,MAAM,IAAI,MAAM;IAiBhB;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM;IAqBnC;;;;OAIG;IACH,IAAI,IAAI,MAAM;IAqBd;;;OAGG;IACH,OAAO,IAAI,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAatC;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,MAAM,IAAI,CAAC,GAAG,IAAI;IAIlB;;OAEG;IACH,OAAO,IAAI,CAAC,GAAG,IAAI;IAInB;;OAEG;IACH,MAAM,IAAI,OAAO;CAGlB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC/C,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,IAAI,EAAE,CAAC,GAAG,IAAI,GACb,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CA8B7B"}
|