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
|
@@ -34,38 +34,14 @@ export type Primitive =
|
|
|
34
34
|
| null
|
|
35
35
|
| undefined;
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
* If you want to reference an existing database, use `Database.Named(name)` as it is a
|
|
42
|
-
* compile error to create duplicate databases.
|
|
43
|
-
*/
|
|
44
|
-
export class SQLDatabase {
|
|
45
|
-
private readonly impl: runtime.SQLDatabase;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Creates a new database with the given name and configuration
|
|
49
|
-
*/
|
|
50
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
51
|
-
constructor(name: string, cfg?: SQLDatabaseConfig) {
|
|
52
|
-
this.impl = runtime.RT.sqlDatabase(name);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Reference an existing database by name, if the database doesn't
|
|
57
|
-
* exist yet, use `new Database(name)` instead.
|
|
58
|
-
*/
|
|
59
|
-
static named<name extends string>(name: StringLiteral<name>): SQLDatabase {
|
|
60
|
-
return new SQLDatabase(name);
|
|
61
|
-
}
|
|
37
|
+
type SQLQueryExecutor =
|
|
38
|
+
| runtime.SQLConn
|
|
39
|
+
| runtime.SQLDatabase
|
|
40
|
+
| runtime.Transaction;
|
|
62
41
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
get connectionString(): string {
|
|
67
|
-
return this.impl.connString();
|
|
68
|
-
}
|
|
42
|
+
/** Base class containing shared query functionality */
|
|
43
|
+
class BaseQueryExecutor {
|
|
44
|
+
constructor(protected readonly impl: SQLQueryExecutor) {}
|
|
69
45
|
|
|
70
46
|
/**
|
|
71
47
|
* query queries the database using a template string, replacing your placeholders in the template
|
|
@@ -92,9 +68,7 @@ export class SQLDatabase {
|
|
|
92
68
|
const cursor = await this.impl.query(query, args, source);
|
|
93
69
|
while (true) {
|
|
94
70
|
const row = await cursor.next();
|
|
95
|
-
if (row === null)
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
71
|
+
if (row === null) break;
|
|
98
72
|
yield row.values() as T;
|
|
99
73
|
}
|
|
100
74
|
}
|
|
@@ -125,10 +99,7 @@ export class SQLDatabase {
|
|
|
125
99
|
const result = await this.impl.query(query, args, source);
|
|
126
100
|
while (true) {
|
|
127
101
|
const row = await result.next();
|
|
128
|
-
if (row === null)
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
|
-
|
|
102
|
+
if (row === null) break;
|
|
132
103
|
yield row.values() as T;
|
|
133
104
|
}
|
|
134
105
|
}
|
|
@@ -158,12 +129,9 @@ export class SQLDatabase {
|
|
|
158
129
|
const result: T[] = [];
|
|
159
130
|
while (true) {
|
|
160
131
|
const row = await cursor.next();
|
|
161
|
-
if (row === null)
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
132
|
+
if (row === null) break;
|
|
164
133
|
result.push(row.values() as T);
|
|
165
134
|
}
|
|
166
|
-
|
|
167
135
|
return result;
|
|
168
136
|
}
|
|
169
137
|
|
|
@@ -189,12 +157,9 @@ export class SQLDatabase {
|
|
|
189
157
|
const result: T[] = [];
|
|
190
158
|
while (true) {
|
|
191
159
|
const row = await cursor.next();
|
|
192
|
-
if (row === null)
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
160
|
+
if (row === null) break;
|
|
195
161
|
result.push(row.values() as T);
|
|
196
162
|
}
|
|
197
|
-
|
|
198
163
|
return result;
|
|
199
164
|
}
|
|
200
165
|
|
|
@@ -216,10 +181,8 @@ export class SQLDatabase {
|
|
|
216
181
|
const args = buildQueryArgs(params);
|
|
217
182
|
const source = getCurrentRequest();
|
|
218
183
|
const result = await this.impl.query(query, args, source);
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return row ? (row.values() as T) : null;
|
|
222
|
-
}
|
|
184
|
+
const row = await result.next();
|
|
185
|
+
return row ? (row.values() as T) : null;
|
|
223
186
|
}
|
|
224
187
|
|
|
225
188
|
/**
|
|
@@ -244,10 +207,8 @@ export class SQLDatabase {
|
|
|
244
207
|
const args = buildQueryArgs(params);
|
|
245
208
|
const source = getCurrentRequest();
|
|
246
209
|
const result = await this.impl.query(query, args, source);
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return row ? (row.values() as T) : null;
|
|
250
|
-
}
|
|
210
|
+
const row = await result.next();
|
|
211
|
+
return row ? (row.values() as T) : null;
|
|
251
212
|
}
|
|
252
213
|
|
|
253
214
|
/**
|
|
@@ -267,7 +228,7 @@ export class SQLDatabase {
|
|
|
267
228
|
|
|
268
229
|
// Need to await the cursor to process any errors from things like
|
|
269
230
|
// unique constraint violations.
|
|
270
|
-
|
|
231
|
+
const cur = await this.impl.query(query, args, source);
|
|
271
232
|
await cur.next();
|
|
272
233
|
}
|
|
273
234
|
|
|
@@ -289,263 +250,112 @@ export class SQLDatabase {
|
|
|
289
250
|
|
|
290
251
|
// Need to await the cursor to process any errors from things like
|
|
291
252
|
// unique constraint violations.
|
|
292
|
-
|
|
253
|
+
const cur = await this.impl.query(query, args, source);
|
|
293
254
|
await cur.next();
|
|
294
255
|
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Acquires a database connection from the database pool.
|
|
298
|
-
*
|
|
299
|
-
* When the connection is closed or is garbage-collected, it is returned to the pool.
|
|
300
|
-
* @returns a new connection to the database
|
|
301
|
-
*/
|
|
302
|
-
async acquire(): Promise<Connection> {
|
|
303
|
-
const impl = await this.impl.acquire();
|
|
304
|
-
return new Connection(impl);
|
|
305
|
-
}
|
|
306
256
|
}
|
|
307
257
|
|
|
308
258
|
/**
|
|
309
|
-
*
|
|
259
|
+
* Constructing a new database object will result in Encore provisioning a database with
|
|
260
|
+
* that name and returning this object to represent it.
|
|
261
|
+
*
|
|
262
|
+
* If you want to reference an existing database, use `Database.Named(name)` as it is a
|
|
263
|
+
* compile error to create duplicate databases.
|
|
310
264
|
*/
|
|
311
|
-
export class
|
|
312
|
-
|
|
265
|
+
export class SQLDatabase extends BaseQueryExecutor {
|
|
266
|
+
protected declare readonly impl: runtime.SQLDatabase;
|
|
313
267
|
|
|
314
|
-
constructor(
|
|
315
|
-
|
|
268
|
+
constructor(name: string, cfg?: SQLDatabaseConfig) {
|
|
269
|
+
super(runtime.RT.sqlDatabase(name));
|
|
316
270
|
}
|
|
317
271
|
|
|
318
272
|
/**
|
|
319
|
-
*
|
|
273
|
+
* Reference an existing database by name, if the database doesn't
|
|
274
|
+
* exist yet, use `new Database(name)` instead.
|
|
320
275
|
*/
|
|
321
|
-
|
|
322
|
-
|
|
276
|
+
static named<name extends string>(name: StringLiteral<name>): SQLDatabase {
|
|
277
|
+
return new SQLDatabase(name);
|
|
323
278
|
}
|
|
324
279
|
|
|
325
280
|
/**
|
|
326
|
-
*
|
|
327
|
-
* with parametrised values without risking SQL injections.
|
|
328
|
-
*
|
|
329
|
-
* It returns an async generator, that allows iterating over the results
|
|
330
|
-
* in a streaming fashion using `for await`.
|
|
331
|
-
*
|
|
332
|
-
* @example
|
|
333
|
-
*
|
|
334
|
-
* const email = "foo@example.com";
|
|
335
|
-
* const result = database.query`SELECT id FROM users WHERE email=${email}`
|
|
336
|
-
*
|
|
337
|
-
* This produces the query: "SELECT id FROM users WHERE email=$1".
|
|
281
|
+
* Returns the connection string for the database
|
|
338
282
|
*/
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
strings: TemplateStringsArray,
|
|
342
|
-
...params: Primitive[]
|
|
343
|
-
): AsyncGenerator<T> {
|
|
344
|
-
const query = buildQuery(strings, params);
|
|
345
|
-
const args = buildQueryArgs(params);
|
|
346
|
-
const source = getCurrentRequest();
|
|
347
|
-
const cursor = await this.impl.query(query, args, source);
|
|
348
|
-
while (true) {
|
|
349
|
-
const row = await cursor.next();
|
|
350
|
-
if (row === null) {
|
|
351
|
-
break;
|
|
352
|
-
}
|
|
353
|
-
yield row.values() as T;
|
|
354
|
-
}
|
|
283
|
+
get connectionString(): string {
|
|
284
|
+
return this.impl.connString();
|
|
355
285
|
}
|
|
356
286
|
|
|
357
287
|
/**
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
* It returns an async generator, that allows iterating over the results
|
|
361
|
-
* in a streaming fashion using `for await`.
|
|
362
|
-
*
|
|
363
|
-
* @example
|
|
364
|
-
* const query = "SELECT id FROM users WHERE email=$1";
|
|
365
|
-
* const email = "foo@example.com";
|
|
366
|
-
* for await (const row of database.rawQuery(query, email)) {
|
|
367
|
-
* console.log(row);
|
|
368
|
-
* }
|
|
288
|
+
* Acquires a database connection from the database pool.
|
|
369
289
|
*
|
|
370
|
-
*
|
|
371
|
-
* @
|
|
372
|
-
* @returns An async generator that yields rows from the query result.
|
|
290
|
+
* When the connection is closed or is garbage-collected, it is returned to the pool.
|
|
291
|
+
* @returns a new connection to the database
|
|
373
292
|
*/
|
|
374
|
-
async
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
): AsyncGenerator<T> {
|
|
378
|
-
const args = buildQueryArgs(params);
|
|
379
|
-
const source = getCurrentRequest();
|
|
380
|
-
const result = await this.impl.query(query, args, source);
|
|
381
|
-
while (true) {
|
|
382
|
-
const row = await result.next();
|
|
383
|
-
if (row === null) {
|
|
384
|
-
break;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
yield row.values() as T;
|
|
388
|
-
}
|
|
293
|
+
async acquire(): Promise<Connection> {
|
|
294
|
+
const impl = await this.impl.acquire();
|
|
295
|
+
return new Connection(impl);
|
|
389
296
|
}
|
|
390
297
|
|
|
391
298
|
/**
|
|
392
|
-
*
|
|
393
|
-
* with parametrised values without risking SQL injections.
|
|
394
|
-
*
|
|
395
|
-
* It returns an array of all results.
|
|
396
|
-
*
|
|
397
|
-
* @example
|
|
299
|
+
* Begins a database transaction.
|
|
398
300
|
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
401
|
-
*
|
|
402
|
-
* This produces the query: "SELECT id FROM users WHERE email=$1".
|
|
301
|
+
* Make sure to always call `rollback` or `commit` to prevent hanging transactions.
|
|
302
|
+
* @returns a transaction object that implements AsycDisposable
|
|
403
303
|
*/
|
|
404
|
-
|
|
405
|
-
async queryAll<T extends Row = Record<string, any>>(
|
|
406
|
-
strings: TemplateStringsArray,
|
|
407
|
-
...params: Primitive[]
|
|
408
|
-
): Promise<T[]> {
|
|
409
|
-
const query = buildQuery(strings, params);
|
|
410
|
-
const args = buildQueryArgs(params);
|
|
304
|
+
async begin(): Promise<Transaction> {
|
|
411
305
|
const source = getCurrentRequest();
|
|
412
|
-
const
|
|
413
|
-
|
|
414
|
-
while (true) {
|
|
415
|
-
const row = await cursor.next();
|
|
416
|
-
if (row === null) {
|
|
417
|
-
break;
|
|
418
|
-
}
|
|
419
|
-
result.push(row.values() as T);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
return result;
|
|
306
|
+
const impl = await this.impl.begin(source);
|
|
307
|
+
return new Transaction(impl);
|
|
423
308
|
}
|
|
309
|
+
}
|
|
424
310
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
* It returns an array of all results.
|
|
429
|
-
*
|
|
430
|
-
* @example
|
|
431
|
-
*
|
|
432
|
-
* const query = "SELECT id FROM users WHERE email=$1";
|
|
433
|
-
* const email = "foo@example.com";
|
|
434
|
-
* const rows = await database.rawQueryAll(query, email);
|
|
435
|
-
*/
|
|
436
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
437
|
-
async rawQueryAll<T extends Row = Record<string, any>>(
|
|
438
|
-
query: string,
|
|
439
|
-
...params: Primitive[]
|
|
440
|
-
): Promise<T[]> {
|
|
441
|
-
const args = buildQueryArgs(params);
|
|
442
|
-
const source = getCurrentRequest();
|
|
443
|
-
const cursor = await this.impl.query(query, args, source);
|
|
444
|
-
const result: T[] = [];
|
|
445
|
-
while (true) {
|
|
446
|
-
const row = await cursor.next();
|
|
447
|
-
if (row === null) {
|
|
448
|
-
break;
|
|
449
|
-
}
|
|
450
|
-
result.push(row.values() as T);
|
|
451
|
-
}
|
|
311
|
+
export class Transaction extends BaseQueryExecutor implements AsyncDisposable {
|
|
312
|
+
protected declare readonly impl: runtime.Transaction;
|
|
313
|
+
private done: boolean = false;
|
|
452
314
|
|
|
453
|
-
|
|
315
|
+
constructor(impl: runtime.Transaction) {
|
|
316
|
+
super(impl);
|
|
454
317
|
}
|
|
455
318
|
|
|
456
319
|
/**
|
|
457
|
-
*
|
|
458
|
-
* If the query selects no rows it returns null.
|
|
459
|
-
* Otherwise it returns the first row and discards the rest.
|
|
460
|
-
*
|
|
461
|
-
* @example
|
|
462
|
-
* const email = "foo@example.com";
|
|
463
|
-
* const result = database.queryRow`SELECT id FROM users WHERE email=${email}`
|
|
320
|
+
* Commit the transaction.
|
|
464
321
|
*/
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
strings: TemplateStringsArray,
|
|
468
|
-
...params: Primitive[]
|
|
469
|
-
): Promise<T | null> {
|
|
470
|
-
const query = buildQuery(strings, params);
|
|
471
|
-
const args = buildQueryArgs(params);
|
|
322
|
+
async commit() {
|
|
323
|
+
this.done = true;
|
|
472
324
|
const source = getCurrentRequest();
|
|
473
|
-
|
|
474
|
-
while (true) {
|
|
475
|
-
const row = await result.next();
|
|
476
|
-
return row ? (row.values() as T) : null;
|
|
477
|
-
}
|
|
325
|
+
await this.impl.commit(source);
|
|
478
326
|
}
|
|
479
327
|
|
|
480
328
|
/**
|
|
481
|
-
*
|
|
482
|
-
* If the query selects no rows, it returns null.
|
|
483
|
-
* Otherwise, it returns the first row and discards the rest.
|
|
484
|
-
*
|
|
485
|
-
* @example
|
|
486
|
-
* const query = "SELECT id FROM users WHERE email=$1";
|
|
487
|
-
* const email = "foo@example.com";
|
|
488
|
-
* const result = await database.rawQueryRow(query, email);
|
|
489
|
-
* console.log(result);
|
|
490
|
-
*
|
|
491
|
-
* @param query - The raw SQL query string.
|
|
492
|
-
* @param params - The parameters to be used in the query.
|
|
493
|
-
* @returns A promise that resolves to a single row or null.
|
|
329
|
+
* Rollback the transaction.
|
|
494
330
|
*/
|
|
495
|
-
async
|
|
496
|
-
|
|
497
|
-
...params: Primitive[]
|
|
498
|
-
): Promise<T | null> {
|
|
499
|
-
const args = buildQueryArgs(params);
|
|
331
|
+
async rollback() {
|
|
332
|
+
this.done = true;
|
|
500
333
|
const source = getCurrentRequest();
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
334
|
+
await this.impl.rollback(source);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
async [Symbol.asyncDispose]() {
|
|
338
|
+
if (!this.done) {
|
|
339
|
+
await this.rollback();
|
|
505
340
|
}
|
|
506
341
|
}
|
|
342
|
+
}
|
|
507
343
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
* const result = database.exec`DELETE FROM users WHERE email=${email}`
|
|
514
|
-
*/
|
|
515
|
-
async exec(
|
|
516
|
-
strings: TemplateStringsArray,
|
|
517
|
-
...params: Primitive[]
|
|
518
|
-
): Promise<void> {
|
|
519
|
-
const query = buildQuery(strings, params);
|
|
520
|
-
const args = buildQueryArgs(params);
|
|
521
|
-
const source = getCurrentRequest();
|
|
344
|
+
/**
|
|
345
|
+
* Represents a dedicated connection to a database.
|
|
346
|
+
*/
|
|
347
|
+
export class Connection extends BaseQueryExecutor {
|
|
348
|
+
protected declare readonly impl: runtime.SQLConn;
|
|
522
349
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
let cur = await this.impl.query(query, args, source);
|
|
526
|
-
await cur.next();
|
|
350
|
+
constructor(impl: runtime.SQLConn) {
|
|
351
|
+
super(impl);
|
|
527
352
|
}
|
|
528
353
|
|
|
529
354
|
/**
|
|
530
|
-
*
|
|
531
|
-
*
|
|
532
|
-
* @example
|
|
533
|
-
* const query = "DELETE FROM users WHERE email=$1";
|
|
534
|
-
* const email = "foo@example.com";
|
|
535
|
-
* await database.rawExec(query, email);
|
|
536
|
-
*
|
|
537
|
-
* @param query - The raw SQL query string.
|
|
538
|
-
* @param params - The parameters to be used in the query.
|
|
539
|
-
* @returns A promise that resolves when the query has been executed.
|
|
355
|
+
* Returns the connection to the database pool.
|
|
540
356
|
*/
|
|
541
|
-
async
|
|
542
|
-
|
|
543
|
-
const source = getCurrentRequest();
|
|
544
|
-
|
|
545
|
-
// Need to await the cursor to process any errors from things like
|
|
546
|
-
// unique constraint violations.
|
|
547
|
-
let cur = await this.impl.query(query, args, source);
|
|
548
|
-
await cur.next();
|
|
357
|
+
async close() {
|
|
358
|
+
await this.impl.close();
|
|
549
359
|
}
|
|
550
360
|
}
|
|
551
361
|
|