encore.dev 1.46.16 → 1.46.18
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/internal/runtime/napi/napi.cjs +3 -1
- package/dist/internal/runtime/napi/napi.d.cts +8 -0
- package/dist/storage/sqldb/database.d.ts +47 -127
- package/dist/storage/sqldb/database.js +68 -229
- package/dist/storage/sqldb/database.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/internal/runtime/napi/napi.cjs +3 -1
- package/internal/runtime/napi/napi.d.cts +8 -0
- package/package.json +1 -1
- package/storage/sqldb/database.ts +75 -265
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// The version of the runtime this JS bundle was generated for.
|
|
2
|
-
const version = "v1.46.
|
|
2
|
+
const version = "v1.46.18";
|
|
3
3
|
|
|
4
4
|
// Load the native module.
|
|
5
5
|
const nativeModulePath = process.env.ENCORE_RUNTIME_LIB;
|
|
@@ -42,6 +42,7 @@ const {
|
|
|
42
42
|
SqlConn,
|
|
43
43
|
SqlDatabase,
|
|
44
44
|
Stream,
|
|
45
|
+
Transaction,
|
|
45
46
|
TypedObjectError,
|
|
46
47
|
WebSocketClient,
|
|
47
48
|
} = nativeModule;
|
|
@@ -78,6 +79,7 @@ module.exports = {
|
|
|
78
79
|
SqlConn,
|
|
79
80
|
SqlDatabase,
|
|
80
81
|
Stream,
|
|
82
|
+
Transaction,
|
|
81
83
|
TypedObjectError,
|
|
82
84
|
WebSocketClient,
|
|
83
85
|
};
|
|
@@ -303,6 +303,8 @@ export class SqlDatabase {
|
|
|
303
303
|
acquire(): Promise<SQLConn>
|
|
304
304
|
/** Reports the connection string to connect to this database. */
|
|
305
305
|
connString(): string
|
|
306
|
+
/** Begins a transaction */
|
|
307
|
+
begin(source?: Request | undefined | null): Promise<Transaction>
|
|
306
308
|
query(query: string, args: QueryArgs, source?: Request | undefined | null): Promise<Cursor>
|
|
307
309
|
queryRow(query: string, args: QueryArgs, source?: Request | undefined | null): Promise<Row | null>
|
|
308
310
|
}
|
|
@@ -320,6 +322,12 @@ export interface TraceData {
|
|
|
320
322
|
extCorrelationId?: string
|
|
321
323
|
}
|
|
322
324
|
|
|
325
|
+
export class Transaction {
|
|
326
|
+
commit(source?: Request | undefined | null): Promise<void>
|
|
327
|
+
rollback(source?: Request | undefined | null): Promise<void>
|
|
328
|
+
query(query: string, args: QueryArgs, source?: Request | undefined | null): Promise<Cursor>
|
|
329
|
+
}
|
|
330
|
+
|
|
323
331
|
export class TypedObjectError {
|
|
324
332
|
kind: ObjectErrorKind
|
|
325
333
|
message: string
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
import * as runtime from "../../internal/runtime/mod.js";
|
|
3
4
|
import { StringLiteral } from "../../internal/utils/constraints.js";
|
|
4
5
|
export interface SQLMigrationsConfig {
|
|
@@ -14,28 +15,11 @@ export interface SQLDatabaseConfig {
|
|
|
14
15
|
export type Row = Record<string, any>;
|
|
15
16
|
/** Represents a type that can be used in query template literals */
|
|
16
17
|
export type Primitive = string | string[] | number | number[] | boolean | boolean[] | Buffer | Date | Date[] | Record<string, any> | Record<string, any>[] | null | undefined;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* compile error to create duplicate databases.
|
|
23
|
-
*/
|
|
24
|
-
export declare class SQLDatabase {
|
|
25
|
-
private readonly impl;
|
|
26
|
-
/**
|
|
27
|
-
* Creates a new database with the given name and configuration
|
|
28
|
-
*/
|
|
29
|
-
constructor(name: string, cfg?: SQLDatabaseConfig);
|
|
30
|
-
/**
|
|
31
|
-
* Reference an existing database by name, if the database doesn't
|
|
32
|
-
* exist yet, use `new Database(name)` instead.
|
|
33
|
-
*/
|
|
34
|
-
static named<name extends string>(name: StringLiteral<name>): SQLDatabase;
|
|
35
|
-
/**
|
|
36
|
-
* Returns the connection string for the database
|
|
37
|
-
*/
|
|
38
|
-
get connectionString(): string;
|
|
18
|
+
type SQLQueryExecutor = runtime.SQLConn | runtime.SQLDatabase | runtime.Transaction;
|
|
19
|
+
/** Base class containing shared query functionality */
|
|
20
|
+
declare class BaseQueryExecutor {
|
|
21
|
+
protected readonly impl: SQLQueryExecutor;
|
|
22
|
+
constructor(impl: SQLQueryExecutor);
|
|
39
23
|
/**
|
|
40
24
|
* query queries the database using a template string, replacing your placeholders in the template
|
|
41
25
|
* with parametrised values without risking SQL injections.
|
|
@@ -142,128 +126,64 @@ export declare class SQLDatabase {
|
|
|
142
126
|
* @returns A promise that resolves when the query has been executed.
|
|
143
127
|
*/
|
|
144
128
|
rawExec(query: string, ...params: Primitive[]): Promise<void>;
|
|
145
|
-
/**
|
|
146
|
-
* Acquires a database connection from the database pool.
|
|
147
|
-
*
|
|
148
|
-
* When the connection is closed or is garbage-collected, it is returned to the pool.
|
|
149
|
-
* @returns a new connection to the database
|
|
150
|
-
*/
|
|
151
|
-
acquire(): Promise<Connection>;
|
|
152
129
|
}
|
|
153
130
|
/**
|
|
154
|
-
*
|
|
131
|
+
* Constructing a new database object will result in Encore provisioning a database with
|
|
132
|
+
* that name and returning this object to represent it.
|
|
133
|
+
*
|
|
134
|
+
* If you want to reference an existing database, use `Database.Named(name)` as it is a
|
|
135
|
+
* compile error to create duplicate databases.
|
|
155
136
|
*/
|
|
156
|
-
export declare class
|
|
157
|
-
|
|
158
|
-
constructor(
|
|
159
|
-
/**
|
|
160
|
-
* Returns the connection to the database pool.
|
|
161
|
-
*/
|
|
162
|
-
close(): Promise<void>;
|
|
163
|
-
/**
|
|
164
|
-
* query queries the database using a template string, replacing your placeholders in the template
|
|
165
|
-
* with parametrised values without risking SQL injections.
|
|
166
|
-
*
|
|
167
|
-
* It returns an async generator, that allows iterating over the results
|
|
168
|
-
* in a streaming fashion using `for await`.
|
|
169
|
-
*
|
|
170
|
-
* @example
|
|
171
|
-
*
|
|
172
|
-
* const email = "foo@example.com";
|
|
173
|
-
* const result = database.query`SELECT id FROM users WHERE email=${email}`
|
|
174
|
-
*
|
|
175
|
-
* This produces the query: "SELECT id FROM users WHERE email=$1".
|
|
176
|
-
*/
|
|
177
|
-
query<T extends Row = Record<string, any>>(strings: TemplateStringsArray, ...params: Primitive[]): AsyncGenerator<T>;
|
|
137
|
+
export declare class SQLDatabase extends BaseQueryExecutor {
|
|
138
|
+
protected readonly impl: runtime.SQLDatabase;
|
|
139
|
+
constructor(name: string, cfg?: SQLDatabaseConfig);
|
|
178
140
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* It returns an async generator, that allows iterating over the results
|
|
182
|
-
* in a streaming fashion using `for await`.
|
|
183
|
-
*
|
|
184
|
-
* @example
|
|
185
|
-
* const query = "SELECT id FROM users WHERE email=$1";
|
|
186
|
-
* const email = "foo@example.com";
|
|
187
|
-
* for await (const row of database.rawQuery(query, email)) {
|
|
188
|
-
* console.log(row);
|
|
189
|
-
* }
|
|
190
|
-
*
|
|
191
|
-
* @param query - The raw SQL query string.
|
|
192
|
-
* @param params - The parameters to be used in the query.
|
|
193
|
-
* @returns An async generator that yields rows from the query result.
|
|
141
|
+
* Reference an existing database by name, if the database doesn't
|
|
142
|
+
* exist yet, use `new Database(name)` instead.
|
|
194
143
|
*/
|
|
195
|
-
|
|
144
|
+
static named<name extends string>(name: StringLiteral<name>): SQLDatabase;
|
|
196
145
|
/**
|
|
197
|
-
*
|
|
198
|
-
* with parametrised values without risking SQL injections.
|
|
199
|
-
*
|
|
200
|
-
* It returns an array of all results.
|
|
201
|
-
*
|
|
202
|
-
* @example
|
|
203
|
-
*
|
|
204
|
-
* const email = "foo@example.com";
|
|
205
|
-
* const result = database.queryAll`SELECT id FROM users WHERE email=${email}`
|
|
206
|
-
*
|
|
207
|
-
* This produces the query: "SELECT id FROM users WHERE email=$1".
|
|
146
|
+
* Returns the connection string for the database
|
|
208
147
|
*/
|
|
209
|
-
|
|
148
|
+
get connectionString(): string;
|
|
210
149
|
/**
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* It returns an array of all results.
|
|
214
|
-
*
|
|
215
|
-
* @example
|
|
150
|
+
* Acquires a database connection from the database pool.
|
|
216
151
|
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
* const rows = await database.rawQueryAll(query, email);
|
|
152
|
+
* When the connection is closed or is garbage-collected, it is returned to the pool.
|
|
153
|
+
* @returns a new connection to the database
|
|
220
154
|
*/
|
|
221
|
-
|
|
155
|
+
acquire(): Promise<Connection>;
|
|
222
156
|
/**
|
|
223
|
-
*
|
|
224
|
-
* If the query selects no rows it returns null.
|
|
225
|
-
* Otherwise it returns the first row and discards the rest.
|
|
157
|
+
* Begins a database transaction.
|
|
226
158
|
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
* const result = database.queryRow`SELECT id FROM users WHERE email=${email}`
|
|
159
|
+
* Make sure to always call `rollback` or `commit` to prevent hanging transactions.
|
|
160
|
+
* @returns a transaction object that implements AsycDisposable
|
|
230
161
|
*/
|
|
231
|
-
|
|
162
|
+
begin(): Promise<Transaction>;
|
|
163
|
+
}
|
|
164
|
+
export declare class Transaction extends BaseQueryExecutor implements AsyncDisposable {
|
|
165
|
+
protected readonly impl: runtime.Transaction;
|
|
166
|
+
private done;
|
|
167
|
+
constructor(impl: runtime.Transaction);
|
|
232
168
|
/**
|
|
233
|
-
*
|
|
234
|
-
* If the query selects no rows, it returns null.
|
|
235
|
-
* Otherwise, it returns the first row and discards the rest.
|
|
236
|
-
*
|
|
237
|
-
* @example
|
|
238
|
-
* const query = "SELECT id FROM users WHERE email=$1";
|
|
239
|
-
* const email = "foo@example.com";
|
|
240
|
-
* const result = await database.rawQueryRow(query, email);
|
|
241
|
-
* console.log(result);
|
|
242
|
-
*
|
|
243
|
-
* @param query - The raw SQL query string.
|
|
244
|
-
* @param params - The parameters to be used in the query.
|
|
245
|
-
* @returns A promise that resolves to a single row or null.
|
|
169
|
+
* Commit the transaction.
|
|
246
170
|
*/
|
|
247
|
-
|
|
171
|
+
commit(): Promise<void>;
|
|
248
172
|
/**
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
* @example
|
|
252
|
-
* const email = "foo@example.com";
|
|
253
|
-
* const result = database.exec`DELETE FROM users WHERE email=${email}`
|
|
173
|
+
* Rollback the transaction.
|
|
254
174
|
*/
|
|
255
|
-
|
|
175
|
+
rollback(): Promise<void>;
|
|
176
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Represents a dedicated connection to a database.
|
|
180
|
+
*/
|
|
181
|
+
export declare class Connection extends BaseQueryExecutor {
|
|
182
|
+
protected readonly impl: runtime.SQLConn;
|
|
183
|
+
constructor(impl: runtime.SQLConn);
|
|
256
184
|
/**
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
* @example
|
|
260
|
-
* const query = "DELETE FROM users WHERE email=$1";
|
|
261
|
-
* const email = "foo@example.com";
|
|
262
|
-
* await database.rawExec(query, email);
|
|
263
|
-
*
|
|
264
|
-
* @param query - The raw SQL query string.
|
|
265
|
-
* @param params - The parameters to be used in the query.
|
|
266
|
-
* @returns A promise that resolves when the query has been executed.
|
|
185
|
+
* Returns the connection to the database pool.
|
|
267
186
|
*/
|
|
268
|
-
|
|
187
|
+
close(): Promise<void>;
|
|
269
188
|
}
|
|
189
|
+
export {};
|
|
@@ -1,34 +1,11 @@
|
|
|
1
1
|
import { getCurrentRequest } from "../../internal/reqtrack/mod.js";
|
|
2
2
|
import * as runtime from "../../internal/runtime/mod.js";
|
|
3
3
|
const driverName = "node-pg";
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
* that name and returning this object to represent it.
|
|
7
|
-
*
|
|
8
|
-
* If you want to reference an existing database, use `Database.Named(name)` as it is a
|
|
9
|
-
* compile error to create duplicate databases.
|
|
10
|
-
*/
|
|
11
|
-
export class SQLDatabase {
|
|
4
|
+
/** Base class containing shared query functionality */
|
|
5
|
+
class BaseQueryExecutor {
|
|
12
6
|
impl;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*/
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17
|
-
constructor(name, cfg) {
|
|
18
|
-
this.impl = runtime.RT.sqlDatabase(name);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Reference an existing database by name, if the database doesn't
|
|
22
|
-
* exist yet, use `new Database(name)` instead.
|
|
23
|
-
*/
|
|
24
|
-
static named(name) {
|
|
25
|
-
return new SQLDatabase(name);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Returns the connection string for the database
|
|
29
|
-
*/
|
|
30
|
-
get connectionString() {
|
|
31
|
-
return this.impl.connString();
|
|
7
|
+
constructor(impl) {
|
|
8
|
+
this.impl = impl;
|
|
32
9
|
}
|
|
33
10
|
/**
|
|
34
11
|
* query queries the database using a template string, replacing your placeholders in the template
|
|
@@ -52,9 +29,8 @@ export class SQLDatabase {
|
|
|
52
29
|
const cursor = await this.impl.query(query, args, source);
|
|
53
30
|
while (true) {
|
|
54
31
|
const row = await cursor.next();
|
|
55
|
-
if (row === null)
|
|
32
|
+
if (row === null)
|
|
56
33
|
break;
|
|
57
|
-
}
|
|
58
34
|
yield row.values();
|
|
59
35
|
}
|
|
60
36
|
}
|
|
@@ -81,9 +57,8 @@ export class SQLDatabase {
|
|
|
81
57
|
const result = await this.impl.query(query, args, source);
|
|
82
58
|
while (true) {
|
|
83
59
|
const row = await result.next();
|
|
84
|
-
if (row === null)
|
|
60
|
+
if (row === null)
|
|
85
61
|
break;
|
|
86
|
-
}
|
|
87
62
|
yield row.values();
|
|
88
63
|
}
|
|
89
64
|
}
|
|
@@ -109,9 +84,8 @@ export class SQLDatabase {
|
|
|
109
84
|
const result = [];
|
|
110
85
|
while (true) {
|
|
111
86
|
const row = await cursor.next();
|
|
112
|
-
if (row === null)
|
|
87
|
+
if (row === null)
|
|
113
88
|
break;
|
|
114
|
-
}
|
|
115
89
|
result.push(row.values());
|
|
116
90
|
}
|
|
117
91
|
return result;
|
|
@@ -135,9 +109,8 @@ export class SQLDatabase {
|
|
|
135
109
|
const result = [];
|
|
136
110
|
while (true) {
|
|
137
111
|
const row = await cursor.next();
|
|
138
|
-
if (row === null)
|
|
112
|
+
if (row === null)
|
|
139
113
|
break;
|
|
140
|
-
}
|
|
141
114
|
result.push(row.values());
|
|
142
115
|
}
|
|
143
116
|
return result;
|
|
@@ -157,10 +130,8 @@ export class SQLDatabase {
|
|
|
157
130
|
const args = buildQueryArgs(params);
|
|
158
131
|
const source = getCurrentRequest();
|
|
159
132
|
const result = await this.impl.query(query, args, source);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return row ? row.values() : null;
|
|
163
|
-
}
|
|
133
|
+
const row = await result.next();
|
|
134
|
+
return row ? row.values() : null;
|
|
164
135
|
}
|
|
165
136
|
/**
|
|
166
137
|
* rawQueryRow is like rawQuery but returns only a single row.
|
|
@@ -181,10 +152,8 @@ export class SQLDatabase {
|
|
|
181
152
|
const args = buildQueryArgs(params);
|
|
182
153
|
const source = getCurrentRequest();
|
|
183
154
|
const result = await this.impl.query(query, args, source);
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
return row ? row.values() : null;
|
|
187
|
-
}
|
|
155
|
+
const row = await result.next();
|
|
156
|
+
return row ? row.values() : null;
|
|
188
157
|
}
|
|
189
158
|
/**
|
|
190
159
|
* exec executes a query without returning any rows.
|
|
@@ -199,7 +168,7 @@ export class SQLDatabase {
|
|
|
199
168
|
const source = getCurrentRequest();
|
|
200
169
|
// Need to await the cursor to process any errors from things like
|
|
201
170
|
// unique constraint violations.
|
|
202
|
-
|
|
171
|
+
const cur = await this.impl.query(query, args, source);
|
|
203
172
|
await cur.next();
|
|
204
173
|
}
|
|
205
174
|
/**
|
|
@@ -219,225 +188,95 @@ export class SQLDatabase {
|
|
|
219
188
|
const source = getCurrentRequest();
|
|
220
189
|
// Need to await the cursor to process any errors from things like
|
|
221
190
|
// unique constraint violations.
|
|
222
|
-
|
|
191
|
+
const cur = await this.impl.query(query, args, source);
|
|
223
192
|
await cur.next();
|
|
224
193
|
}
|
|
225
|
-
/**
|
|
226
|
-
* Acquires a database connection from the database pool.
|
|
227
|
-
*
|
|
228
|
-
* When the connection is closed or is garbage-collected, it is returned to the pool.
|
|
229
|
-
* @returns a new connection to the database
|
|
230
|
-
*/
|
|
231
|
-
async acquire() {
|
|
232
|
-
const impl = await this.impl.acquire();
|
|
233
|
-
return new Connection(impl);
|
|
234
|
-
}
|
|
235
194
|
}
|
|
236
195
|
/**
|
|
237
|
-
*
|
|
196
|
+
* Constructing a new database object will result in Encore provisioning a database with
|
|
197
|
+
* that name and returning this object to represent it.
|
|
198
|
+
*
|
|
199
|
+
* If you want to reference an existing database, use `Database.Named(name)` as it is a
|
|
200
|
+
* compile error to create duplicate databases.
|
|
238
201
|
*/
|
|
239
|
-
export class
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
this.impl = impl;
|
|
202
|
+
export class SQLDatabase extends BaseQueryExecutor {
|
|
203
|
+
constructor(name, cfg) {
|
|
204
|
+
super(runtime.RT.sqlDatabase(name));
|
|
243
205
|
}
|
|
244
206
|
/**
|
|
245
|
-
*
|
|
207
|
+
* Reference an existing database by name, if the database doesn't
|
|
208
|
+
* exist yet, use `new Database(name)` instead.
|
|
246
209
|
*/
|
|
247
|
-
|
|
248
|
-
|
|
210
|
+
static named(name) {
|
|
211
|
+
return new SQLDatabase(name);
|
|
249
212
|
}
|
|
250
213
|
/**
|
|
251
|
-
*
|
|
252
|
-
* with parametrised values without risking SQL injections.
|
|
253
|
-
*
|
|
254
|
-
* It returns an async generator, that allows iterating over the results
|
|
255
|
-
* in a streaming fashion using `for await`.
|
|
256
|
-
*
|
|
257
|
-
* @example
|
|
258
|
-
*
|
|
259
|
-
* const email = "foo@example.com";
|
|
260
|
-
* const result = database.query`SELECT id FROM users WHERE email=${email}`
|
|
261
|
-
*
|
|
262
|
-
* This produces the query: "SELECT id FROM users WHERE email=$1".
|
|
214
|
+
* Returns the connection string for the database
|
|
263
215
|
*/
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const query = buildQuery(strings, params);
|
|
267
|
-
const args = buildQueryArgs(params);
|
|
268
|
-
const source = getCurrentRequest();
|
|
269
|
-
const cursor = await this.impl.query(query, args, source);
|
|
270
|
-
while (true) {
|
|
271
|
-
const row = await cursor.next();
|
|
272
|
-
if (row === null) {
|
|
273
|
-
break;
|
|
274
|
-
}
|
|
275
|
-
yield row.values();
|
|
276
|
-
}
|
|
216
|
+
get connectionString() {
|
|
217
|
+
return this.impl.connString();
|
|
277
218
|
}
|
|
278
219
|
/**
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
* It returns an async generator, that allows iterating over the results
|
|
282
|
-
* in a streaming fashion using `for await`.
|
|
283
|
-
*
|
|
284
|
-
* @example
|
|
285
|
-
* const query = "SELECT id FROM users WHERE email=$1";
|
|
286
|
-
* const email = "foo@example.com";
|
|
287
|
-
* for await (const row of database.rawQuery(query, email)) {
|
|
288
|
-
* console.log(row);
|
|
289
|
-
* }
|
|
220
|
+
* Acquires a database connection from the database pool.
|
|
290
221
|
*
|
|
291
|
-
*
|
|
292
|
-
* @
|
|
293
|
-
* @returns An async generator that yields rows from the query result.
|
|
222
|
+
* When the connection is closed or is garbage-collected, it is returned to the pool.
|
|
223
|
+
* @returns a new connection to the database
|
|
294
224
|
*/
|
|
295
|
-
async
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
const result = await this.impl.query(query, args, source);
|
|
299
|
-
while (true) {
|
|
300
|
-
const row = await result.next();
|
|
301
|
-
if (row === null) {
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
yield row.values();
|
|
305
|
-
}
|
|
225
|
+
async acquire() {
|
|
226
|
+
const impl = await this.impl.acquire();
|
|
227
|
+
return new Connection(impl);
|
|
306
228
|
}
|
|
307
229
|
/**
|
|
308
|
-
*
|
|
309
|
-
* with parametrised values without risking SQL injections.
|
|
310
|
-
*
|
|
311
|
-
* It returns an array of all results.
|
|
312
|
-
*
|
|
313
|
-
* @example
|
|
314
|
-
*
|
|
315
|
-
* const email = "foo@example.com";
|
|
316
|
-
* const result = database.queryAll`SELECT id FROM users WHERE email=${email}`
|
|
230
|
+
* Begins a database transaction.
|
|
317
231
|
*
|
|
318
|
-
*
|
|
232
|
+
* Make sure to always call `rollback` or `commit` to prevent hanging transactions.
|
|
233
|
+
* @returns a transaction object that implements AsycDisposable
|
|
319
234
|
*/
|
|
320
|
-
|
|
321
|
-
async queryAll(strings, ...params) {
|
|
322
|
-
const query = buildQuery(strings, params);
|
|
323
|
-
const args = buildQueryArgs(params);
|
|
235
|
+
async begin() {
|
|
324
236
|
const source = getCurrentRequest();
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
while (true) {
|
|
328
|
-
const row = await cursor.next();
|
|
329
|
-
if (row === null) {
|
|
330
|
-
break;
|
|
331
|
-
}
|
|
332
|
-
result.push(row.values());
|
|
333
|
-
}
|
|
334
|
-
return result;
|
|
237
|
+
const impl = await this.impl.begin(source);
|
|
238
|
+
return new Transaction(impl);
|
|
335
239
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
* @example
|
|
342
|
-
*
|
|
343
|
-
* const query = "SELECT id FROM users WHERE email=$1";
|
|
344
|
-
* const email = "foo@example.com";
|
|
345
|
-
* const rows = await database.rawQueryAll(query, email);
|
|
346
|
-
*/
|
|
347
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
348
|
-
async rawQueryAll(query, ...params) {
|
|
349
|
-
const args = buildQueryArgs(params);
|
|
350
|
-
const source = getCurrentRequest();
|
|
351
|
-
const cursor = await this.impl.query(query, args, source);
|
|
352
|
-
const result = [];
|
|
353
|
-
while (true) {
|
|
354
|
-
const row = await cursor.next();
|
|
355
|
-
if (row === null) {
|
|
356
|
-
break;
|
|
357
|
-
}
|
|
358
|
-
result.push(row.values());
|
|
359
|
-
}
|
|
360
|
-
return result;
|
|
240
|
+
}
|
|
241
|
+
export class Transaction extends BaseQueryExecutor {
|
|
242
|
+
done = false;
|
|
243
|
+
constructor(impl) {
|
|
244
|
+
super(impl);
|
|
361
245
|
}
|
|
362
246
|
/**
|
|
363
|
-
*
|
|
364
|
-
* If the query selects no rows it returns null.
|
|
365
|
-
* Otherwise it returns the first row and discards the rest.
|
|
366
|
-
*
|
|
367
|
-
* @example
|
|
368
|
-
* const email = "foo@example.com";
|
|
369
|
-
* const result = database.queryRow`SELECT id FROM users WHERE email=${email}`
|
|
247
|
+
* Commit the transaction.
|
|
370
248
|
*/
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
const query = buildQuery(strings, params);
|
|
374
|
-
const args = buildQueryArgs(params);
|
|
249
|
+
async commit() {
|
|
250
|
+
this.done = true;
|
|
375
251
|
const source = getCurrentRequest();
|
|
376
|
-
|
|
377
|
-
while (true) {
|
|
378
|
-
const row = await result.next();
|
|
379
|
-
return row ? row.values() : null;
|
|
380
|
-
}
|
|
252
|
+
await this.impl.commit(source);
|
|
381
253
|
}
|
|
382
254
|
/**
|
|
383
|
-
*
|
|
384
|
-
* If the query selects no rows, it returns null.
|
|
385
|
-
* Otherwise, it returns the first row and discards the rest.
|
|
386
|
-
*
|
|
387
|
-
* @example
|
|
388
|
-
* const query = "SELECT id FROM users WHERE email=$1";
|
|
389
|
-
* const email = "foo@example.com";
|
|
390
|
-
* const result = await database.rawQueryRow(query, email);
|
|
391
|
-
* console.log(result);
|
|
392
|
-
*
|
|
393
|
-
* @param query - The raw SQL query string.
|
|
394
|
-
* @param params - The parameters to be used in the query.
|
|
395
|
-
* @returns A promise that resolves to a single row or null.
|
|
255
|
+
* Rollback the transaction.
|
|
396
256
|
*/
|
|
397
|
-
async
|
|
398
|
-
|
|
257
|
+
async rollback() {
|
|
258
|
+
this.done = true;
|
|
399
259
|
const source = getCurrentRequest();
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
260
|
+
await this.impl.rollback(source);
|
|
261
|
+
}
|
|
262
|
+
async [Symbol.asyncDispose]() {
|
|
263
|
+
if (!this.done) {
|
|
264
|
+
await this.rollback();
|
|
404
265
|
}
|
|
405
266
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
async exec(strings, ...params) {
|
|
414
|
-
const query = buildQuery(strings, params);
|
|
415
|
-
const args = buildQueryArgs(params);
|
|
416
|
-
const source = getCurrentRequest();
|
|
417
|
-
// Need to await the cursor to process any errors from things like
|
|
418
|
-
// unique constraint violations.
|
|
419
|
-
let cur = await this.impl.query(query, args, source);
|
|
420
|
-
await cur.next();
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Represents a dedicated connection to a database.
|
|
270
|
+
*/
|
|
271
|
+
export class Connection extends BaseQueryExecutor {
|
|
272
|
+
constructor(impl) {
|
|
273
|
+
super(impl);
|
|
421
274
|
}
|
|
422
275
|
/**
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
* @example
|
|
426
|
-
* const query = "DELETE FROM users WHERE email=$1";
|
|
427
|
-
* const email = "foo@example.com";
|
|
428
|
-
* await database.rawExec(query, email);
|
|
429
|
-
*
|
|
430
|
-
* @param query - The raw SQL query string.
|
|
431
|
-
* @param params - The parameters to be used in the query.
|
|
432
|
-
* @returns A promise that resolves when the query has been executed.
|
|
276
|
+
* Returns the connection to the database pool.
|
|
433
277
|
*/
|
|
434
|
-
async
|
|
435
|
-
|
|
436
|
-
const source = getCurrentRequest();
|
|
437
|
-
// Need to await the cursor to process any errors from things like
|
|
438
|
-
// unique constraint violations.
|
|
439
|
-
let cur = await this.impl.query(query, args, source);
|
|
440
|
-
await cur.next();
|
|
278
|
+
async close() {
|
|
279
|
+
await this.impl.close();
|
|
441
280
|
}
|
|
442
281
|
}
|
|
443
282
|
function buildQuery(strings, expr) {
|