@@ -19,6 +19,9 @@ import {
19
19
import { Transaction , type TransactionOptions } from "./query/transaction.ts" ;
20
20
import { isTemplateString } from "./utils/utils.ts" ;
21
21
22
+ /**
23
+ * The Session representing the current state of the connection
24
+ */
22
25
export interface Session {
23
26
/**
24
27
* This is the code for the transaction currently locking the connection.
@@ -43,19 +46,31 @@ export interface Session {
43
46
transport : "tcp" | "socket" | undefined ;
44
47
}
45
48
49
+ /**
50
+ * An abstract class used to define common database client properties and methods
51
+ */
46
52
export abstract class QueryClient {
47
53
#connection: Connection ;
48
54
#terminated = false ;
49
55
#transaction: string | null = null ;
50
56
57
+ /**
58
+ * Create a new query client
59
+ */
51
60
constructor ( connection : Connection ) {
52
61
this . #connection = connection ;
53
62
}
54
63
64
+ /**
65
+ * Indicates if the client is currently connected to the database
66
+ */
55
67
get connected ( ) : boolean {
56
68
return this . #connection. connected ;
57
69
}
58
70
71
+ /**
72
+ * The current session metadata
73
+ */
59
74
get session ( ) : Session {
60
75
return {
61
76
current_transaction : this . #transaction,
@@ -71,6 +86,9 @@ export abstract class QueryClient {
71
86
}
72
87
}
73
88
89
+ /**
90
+ * Close the connection to the database
91
+ */
74
92
protected async closeConnection ( ) {
75
93
if ( this . connected ) {
76
94
await this . #connection. end ( ) ;
@@ -87,8 +105,7 @@ export abstract class QueryClient {
87
105
* In order to create a transaction, use the `createTransaction` method in your client as follows:
88
106
*
89
107
* ```ts
90
- * import { Client } from "./client.ts";
91
- *
108
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
92
109
* const client = new Client();
93
110
* const transaction = client.createTransaction("my_transaction_name");
94
111
*
@@ -101,8 +118,7 @@ export abstract class QueryClient {
101
118
* the client without applying any of the changes that took place inside it
102
119
*
103
120
* ```ts
104
- * import { Client } from "./client.ts";
105
- *
121
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
106
122
* const client = new Client();
107
123
* const transaction = client.createTransaction("transaction");
108
124
*
@@ -119,8 +135,7 @@ export abstract class QueryClient {
119
135
* the transaction
120
136
*
121
137
* ```ts
122
- * import { Client } from "./client.ts";
123
- *
138
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
124
139
* const client = new Client();
125
140
* const transaction = client.createTransaction("transaction");
126
141
*
@@ -145,17 +160,15 @@ export abstract class QueryClient {
145
160
* - Repeatable read: This isolates the transaction in a way that any external changes to the data we are reading
146
161
* won't be visible inside the transaction until it has finished
147
162
* ```ts
148
- * import { Client } from "./client.ts";
149
- *
163
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
150
164
* const client = new Client();
151
165
* const transaction = await client.createTransaction("my_transaction", { isolation_level: "repeatable_read" });
152
166
* ```
153
167
*
154
168
* - Serializable: This isolation level prevents the current transaction from making persistent changes
155
169
* if the data they were reading at the beginning of the transaction has been modified (recommended)
156
170
* ```ts
157
- * import { Client } from "./client.ts";
158
- *
171
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
159
172
* const client = new Client();
160
173
* const transaction = await client.createTransaction("my_transaction", { isolation_level: "serializable" });
161
174
* ```
@@ -168,8 +181,7 @@ export abstract class QueryClient {
168
181
* is to in conjuction with the repeatable read isolation, ensuring the data you are reading does not change
169
182
* during the transaction, specially useful for data extraction
170
183
* ```ts
171
- * import { Client } from "./client.ts";
172
- *
184
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
173
185
* const client = new Client();
174
186
* const transaction = await client.createTransaction("my_transaction", { read_only: true });
175
187
* ```
@@ -180,8 +192,7 @@ export abstract class QueryClient {
180
192
* you can do the following:
181
193
*
182
194
* ```ts
183
- * import { Client } from "./client.ts";
184
- *
195
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
185
196
* const client_1 = new Client();
186
197
* const client_2 = new Client();
187
198
* const transaction_1 = client_1.createTransaction("transaction_1");
@@ -246,47 +257,52 @@ export abstract class QueryClient {
246
257
}
247
258
248
259
/**
249
- * This method allows executed queries to be retrieved as array entries.
250
- * It supports a generic interface in order to type the entries retrieved by the query
260
+ * Execute queries and retrieve the data as array entries. It supports a generic in order to type the entries retrieved by the query
251
261
*
252
262
* ```ts
253
- * import { Client } from "./client.ts";
254
- *
263
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
255
264
* const my_client = new Client();
256
265
*
257
- * const {rows} = await my_client.queryArray(
266
+ * const { rows: rows1 } = await my_client.queryArray(
258
267
* "SELECT ID, NAME FROM CLIENTS"
259
268
* ); // Array<unknown[]>
260
- * ```
261
- *
262
- * You can pass type arguments to the query in order to hint TypeScript what the return value will be
263
- * ```ts
264
- * import { Client } from "./client.ts";
265
269
*
266
- * const my_client = new Client();
267
- * const { rows } = await my_client.queryArray<[number, string]>(
270
+ * const { rows: rows2 } = await my_client.queryArray<[number, string]>(
268
271
* "SELECT ID, NAME FROM CLIENTS"
269
272
* ); // Array<[number, string]>
270
273
* ```
274
+ */
275
+ async queryArray < T extends Array < unknown > > (
276
+ query : string ,
277
+ args ?: QueryArguments ,
278
+ ) : Promise < QueryArrayResult < T > > ;
279
+ /**
280
+ * Use the configuration object for more advance options to execute the query
271
281
*
272
- * It also allows you to execute prepared statements with template strings
282
+ * ```ts
283
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
284
+ * const my_client = new Client();
285
+ * const { rows } = await my_client.queryArray<[number, string]>({
286
+ * text: "SELECT ID, NAME FROM CLIENTS",
287
+ * name: "select_clients",
288
+ * }); // Array<[number, string]>
289
+ * ```
290
+ */
291
+ async queryArray < T extends Array < unknown > > (
292
+ config : QueryOptions ,
293
+ ) : Promise < QueryArrayResult < T > > ;
294
+ /**
295
+ * Execute prepared statements with template strings
273
296
*
274
297
* ```ts
275
- * import { Client } from "./client .ts";
298
+ * import { Client } from "https://deno.land/x/postgres/mod .ts";
276
299
* const my_client = new Client();
277
300
*
278
301
* const id = 12;
279
302
* // Array<[number, string]>
280
303
* const {rows} = await my_client.queryArray<[number, string]>`SELECT ID, NAME FROM CLIENTS WHERE ID = ${id}`;
281
304
* ```
282
305
*/
283
- async queryArray < T extends Array < unknown > > (
284
- query : string ,
285
- args ?: QueryArguments ,
286
- ) : Promise < QueryArrayResult < T > > ;
287
- async queryArray < T extends Array < unknown > > (
288
- config : QueryOptions ,
289
- ) : Promise < QueryArrayResult < T > > ;
290
306
async queryArray < T extends Array < unknown > > (
291
307
strings : TemplateStringsArray ,
292
308
...args : unknown [ ]
@@ -324,71 +340,58 @@ export abstract class QueryClient {
324
340
}
325
341
326
342
/**
327
- * This method allows executed queries to be retrieved as object entries.
328
- * It supports a generic interface in order to type the entries retrieved by the query
343
+ * Executed queries and retrieve the data as object entries. It supports a generic in order to type the entries retrieved by the query
329
344
*
330
345
* ```ts
331
- * import { Client } from "./client.ts";
332
- *
346
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
333
347
* const my_client = new Client();
334
348
*
335
- * {
336
- * const { rows } = await my_client.queryObject(
337
- * "SELECT ID, NAME FROM CLIENTS"
338
- * ); // Record<string, unknown>
339
- * }
349
+ * const { rows: rows1 } = await my_client.queryObject(
350
+ * "SELECT ID, NAME FROM CLIENTS"
351
+ * ); // Record<string, unknown>
340
352
*
341
- * {
342
- * const { rows } = await my_client.queryObject<{id: number, name: string}>(
343
- * "SELECT ID, NAME FROM CLIENTS"
344
- * ); // Array<{id: number, name: string}>
345
- * }
353
+ * const { rows: rows2 } = await my_client.queryObject<{id: number, name: string}>(
354
+ * "SELECT ID, NAME FROM CLIENTS"
355
+ * ); // Array<{id: number, name: string}>
346
356
* ```
347
- *
348
- * You can also map the expected results to object fields using the configuration interface.
349
- * This will be assigned in the order they were provided
357
+ */
358
+ async queryObject < T > (
359
+ query : string ,
360
+ args ?: QueryArguments ,
361
+ ) : Promise < QueryObjectResult < T > > ;
362
+ /**
363
+ * Use the configuration object for more advance options to execute the query
350
364
*
351
365
* ```ts
352
- * import { Client } from "./client.ts";
353
- *
366
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
354
367
* const my_client = new Client();
355
368
*
356
- * {
357
- * const {rows} = await my_client.queryObject(
358
- * "SELECT ID, NAME FROM CLIENTS"
359
- * );
360
- *
361
- * console.log(rows); // [{id: 78, name: "Frank"}, {id: 15, name: "Sarah"}]
362
- * }
363
- *
364
- * {
365
- * const {rows} = await my_client.queryObject({
366
- * text: "SELECT ID, NAME FROM CLIENTS",
367
- * fields: ["personal_id", "complete_name"],
368
- * });
369
- *
370
- * console.log(rows); // [{personal_id: 78, complete_name: "Frank"}, {personal_id: 15, complete_name: "Sarah"}]
371
- * }
369
+ * const { rows: rows1 } = await my_client.queryObject(
370
+ * "SELECT ID, NAME FROM CLIENTS"
371
+ * );
372
+ * console.log(rows1); // [{id: 78, name: "Frank"}, {id: 15, name: "Sarah"}]
373
+ *
374
+ * const { rows: rows2 } = await my_client.queryObject({
375
+ * text: "SELECT ID, NAME FROM CLIENTS",
376
+ * fields: ["personal_id", "complete_name"],
377
+ * });
378
+ * console.log(rows2); // [{personal_id: 78, complete_name: "Frank"}, {personal_id: 15, complete_name: "Sarah"}]
372
379
* ```
373
- *
374
- * It also allows you to execute prepared statements with template strings
380
+ */
381
+ async queryObject < T > (
382
+ config : QueryObjectOptions ,
383
+ ) : Promise < QueryObjectResult < T > > ;
384
+ /**
385
+ * Execute prepared statements with template strings
375
386
*
376
387
* ```ts
377
- * import { Client } from "./client.ts";
378
- *
388
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
379
389
* const my_client = new Client();
380
390
* const id = 12;
381
391
* // Array<{id: number, name: string}>
382
392
* const { rows } = await my_client.queryObject<{id: number, name: string}>`SELECT ID, NAME FROM CLIENTS WHERE ID = ${id}`;
383
393
* ```
384
394
*/
385
- async queryObject < T > (
386
- query : string ,
387
- args ?: QueryArguments ,
388
- ) : Promise < QueryObjectResult < T > > ;
389
- async queryObject < T > (
390
- config : QueryObjectOptions ,
391
- ) : Promise < QueryObjectResult < T > > ;
392
395
async queryObject < T > (
393
396
query : TemplateStringsArray ,
394
397
...args : unknown [ ]
@@ -431,6 +434,9 @@ export abstract class QueryClient {
431
434
return await this . #executeQuery< T > ( query ) ;
432
435
}
433
436
437
+ /**
438
+ * Resets the transaction session metadata
439
+ */
434
440
protected resetSessionMetadata ( ) {
435
441
this . #transaction = null ;
436
442
}
@@ -441,8 +447,7 @@ export abstract class QueryClient {
441
447
* statements asynchronously
442
448
*
443
449
* ```ts
444
- * import { Client } from "./client.ts";
445
- *
450
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
446
451
* const client = new Client();
447
452
* await client.connect();
448
453
* await client.queryArray`UPDATE MY_TABLE SET MY_FIELD = 0`;
@@ -453,8 +458,7 @@ export abstract class QueryClient {
453
458
* for concurrency capabilities check out connection pools
454
459
*
455
460
* ```ts
456
- * import { Client } from "./client.ts";
457
- *
461
+ * import { Client } from "https://deno.land/x/postgres/mod.ts";
458
462
* const client_1 = new Client();
459
463
* await client_1.connect();
460
464
* // Even if operations are not awaited, they will be executed in the order they were
@@ -472,6 +476,9 @@ export abstract class QueryClient {
472
476
* ```
473
477
*/
474
478
export class Client extends QueryClient {
479
+ /**
480
+ * Create a new client
481
+ */
475
482
constructor ( config ?: ClientOptions | ConnectionString ) {
476
483
super (
477
484
new Connection ( createParams ( config ) , async ( ) => {
@@ -481,9 +488,15 @@ export class Client extends QueryClient {
481
488
}
482
489
}
483
490
491
+ /**
492
+ * A client used specifically by a connection pool
493
+ */
484
494
export class PoolClient extends QueryClient {
485
495
#release: ( ) => void ;
486
496
497
+ /**
498
+ * Create a new Client used by the pool
499
+ */
487
500
constructor ( config : ClientConfiguration , releaseCallback : ( ) => void ) {
488
501
super (
489
502
new Connection ( config , async ( ) => {
@@ -493,6 +506,9 @@ export class PoolClient extends QueryClient {
493
506
this . #release = releaseCallback ;
494
507
}
495
508
509
+ /**
510
+ * Releases the client back to the pool
511
+ */
496
512
release ( ) {
497
513
this . #release( ) ;
498
514
0 commit comments