@prairielearn/postgres 5.0.2 → 6.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/dist/pool.test.js CHANGED
@@ -2,7 +2,7 @@ import { Writable } from 'node:stream';
2
2
  import { pipeline } from 'node:stream/promises';
3
3
  import { afterAll, assert, beforeAll, describe, expect, it } from 'vitest';
4
4
  import { ZodError, z } from 'zod';
5
- import { callOptionalRow, callRow, callRows, execute, queryAsync, queryCursor, queryOptionalRow, queryRow, queryRows, } from './default-pool.js';
5
+ import { callOptionalRow, callOptionalScalar, callRow, callRows, callScalar, callScalars, execute, queryCursor, queryOptionalRow, queryOptionalScalar, queryRow, queryRows, queryScalar, queryScalars, } from './default-pool.js';
6
6
  import { makePostgresTestUtils } from './test-utils.js';
7
7
  const postgresTestUtils = makePostgresTestUtils({
8
8
  database: 'prairielearn_postgres',
@@ -31,28 +31,28 @@ describe('@prairielearn/postgres', function () {
31
31
  describe('paramsToArray', () => {
32
32
  it('enforces SQL must be a string', async () => {
33
33
  // @ts-expect-error SQL must be a string
34
- const rows = queryAsync({ invalid: true }, {});
34
+ const rows = execute({ invalid: true }, {});
35
35
  await expect(rows).rejects.toThrow('SQL must be a string');
36
36
  });
37
37
  it('enforces params must be array or object', async () => {
38
38
  // @ts-expect-error params must be an array or object
39
- const rows = queryAsync('SELECT 33;', 33);
39
+ const rows = execute('SELECT 33;', 33);
40
40
  await expect(rows).rejects.toThrow('params must be array or object');
41
41
  });
42
42
  it('rejects missing parameters', async () => {
43
- const rows = queryAsync('SELECT $missing;', {});
43
+ const rows = execute('SELECT $missing;', {});
44
44
  await expect(rows).rejects.toThrow('Missing parameter');
45
45
  });
46
46
  it('rejects unused parameters in testing', async () => {
47
- const rows = queryAsync('SELECT 33;', { unsed_parameter: true });
47
+ const rows = execute('SELECT 33;', { unsed_parameter: true });
48
48
  await expect(rows).rejects.toThrow('Unused parameter');
49
49
  });
50
50
  });
51
51
  describe('queryRows', () => {
52
52
  it('handles single column', async () => {
53
- const rows = await queryRows('SELECT id FROM workspaces WHERE id <= 10;', z.string());
53
+ const rows = await queryRows('SELECT id FROM workspaces WHERE id <= 10;', z.object({ id: z.string() }));
54
54
  assert.lengthOf(rows, 10);
55
- assert.equal(rows[0], '1');
55
+ assert.equal(rows[0].id, '1');
56
56
  });
57
57
  it('handles multiple columns', async () => {
58
58
  const rows = await queryRows('SELECT * FROM workspaces WHERE id <= 10;', WorkspaceSchema);
@@ -67,8 +67,8 @@ describe('@prairielearn/postgres', function () {
67
67
  });
68
68
  describe('queryRow', () => {
69
69
  it('handles single column', async () => {
70
- const row = await queryRow('SELECT id FROM workspaces WHERE id = 1;', z.string());
71
- assert.equal(row, '1');
70
+ const row = await queryRow('SELECT id FROM workspaces WHERE id = 1;', z.object({ id: z.string() }));
71
+ assert.equal(row.id, '1');
72
72
  });
73
73
  it('handles multiple columns', async () => {
74
74
  const row = await queryRow('SELECT * FROM workspaces WHERE id = 1;', WorkspaceSchema);
@@ -90,8 +90,8 @@ describe('@prairielearn/postgres', function () {
90
90
  });
91
91
  describe('queryOptionalRow', () => {
92
92
  it('handles single column', async () => {
93
- const row = await queryRow('SELECT id FROM workspaces WHERE id = 1;', z.string());
94
- assert.equal(row, '1');
93
+ const row = await queryRow('SELECT id FROM workspaces WHERE id = 1;', z.object({ id: z.string() }));
94
+ assert.equal(row.id, '1');
95
95
  });
96
96
  it('handles multiple columns', async () => {
97
97
  const row = await queryOptionalRow('SELECT * FROM workspaces WHERE id = 1;', WorkspaceSchema);
@@ -115,14 +115,14 @@ describe('@prairielearn/postgres', function () {
115
115
  });
116
116
  describe('callRows', () => {
117
117
  it('handles single column', async () => {
118
- const rows = await callRows('test_sproc_one_column_ten_rows', z.string());
118
+ const rows = await callRows('test_sproc_one_column_ten_rows', z.object({ id: z.string() }));
119
119
  assert.lengthOf(rows, 10);
120
- assert.equal(rows[0], '1');
120
+ assert.equal(rows[0].id, '1');
121
121
  });
122
122
  it('handles parameters', async () => {
123
- const rows = await callRows('test_sproc_one_column', [10], z.string());
123
+ const rows = await callRows('test_sproc_one_column', [10], z.object({ id: z.string() }));
124
124
  assert.lengthOf(rows, 10);
125
- assert.equal(rows[0], '1');
125
+ assert.equal(rows[0].id, '1');
126
126
  });
127
127
  it('handles multiple columns', async () => {
128
128
  const rows = await callRows('test_sproc_two_columns', [20], SprocTwoColumnsSchema);
@@ -135,12 +135,12 @@ describe('@prairielearn/postgres', function () {
135
135
  });
136
136
  describe('callRow', () => {
137
137
  it('handles single column', async () => {
138
- const row = await callRow('test_sproc_one_column_one_row', z.string());
139
- assert.equal(row, '1');
138
+ const row = await callRow('test_sproc_one_column_one_row', z.object({ id: z.string() }));
139
+ assert.equal(row.id, '1');
140
140
  });
141
141
  it('handles parameters', async () => {
142
- const row = await callRow('test_sproc_one_column', [1], z.string());
143
- assert.equal(row, '1');
142
+ const row = await callRow('test_sproc_one_column', [1], z.object({ id: z.string() }));
143
+ assert.equal(row.id, '1');
144
144
  });
145
145
  it('handles multiple columns', async () => {
146
146
  const row = await callRow('test_sproc_two_columns', [1], SprocTwoColumnsSchema);
@@ -158,12 +158,12 @@ describe('@prairielearn/postgres', function () {
158
158
  });
159
159
  describe('callOptionalRow', () => {
160
160
  it('handles single column', async () => {
161
- const row = await callOptionalRow('test_sproc_one_column_one_row', z.string());
162
- assert.equal(row, '1');
161
+ const row = await callOptionalRow('test_sproc_one_column_one_row', z.object({ id: z.string() }));
162
+ assert.equal(row?.id, '1');
163
163
  });
164
164
  it('handles parameters', async () => {
165
- const row = await callOptionalRow('test_sproc_one_column', [1], z.string());
166
- assert.equal(row, '1');
165
+ const row = await callOptionalRow('test_sproc_one_column', [1], z.object({ id: z.string() }));
166
+ assert.equal(row?.id, '1');
167
167
  });
168
168
  it('handles multiple columns', async () => {
169
169
  const row = await callOptionalRow('test_sproc_two_columns', [1], SprocTwoColumnsSchema);
@@ -180,14 +180,133 @@ describe('@prairielearn/postgres', function () {
180
180
  await expect(rows).rejects.toThrow('Incorrect rowCount: 100');
181
181
  });
182
182
  });
183
+ describe('queryScalars', () => {
184
+ it('returns all scalar values', async () => {
185
+ const ids = await queryScalars('SELECT id FROM workspaces WHERE id <= 10 ORDER BY id ASC;', z.string());
186
+ assert.lengthOf(ids, 10);
187
+ assert.equal(ids[0], '1');
188
+ assert.equal(ids[9], '10');
189
+ });
190
+ it('handles parameters', async () => {
191
+ const ids = await queryScalars('SELECT id FROM workspaces WHERE id <= $1 ORDER BY id ASC;', [5], z.string());
192
+ assert.lengthOf(ids, 5);
193
+ });
194
+ it('rejects multi-column queries', async () => {
195
+ const result = queryScalars('SELECT * FROM workspaces WHERE id <= 10;', z.string());
196
+ await expect(result).rejects.toThrow('Expected exactly one column');
197
+ });
198
+ });
199
+ describe('queryScalar', () => {
200
+ it('returns a single scalar value', async () => {
201
+ const id = await queryScalar('SELECT id FROM workspaces WHERE id = 1;', z.string());
202
+ assert.equal(id, '1');
203
+ });
204
+ it('handles parameters', async () => {
205
+ const id = await queryScalar('SELECT id FROM workspaces WHERE id = $1;', [1], z.string());
206
+ assert.equal(id, '1');
207
+ });
208
+ it('rejects results with zero rows', async () => {
209
+ const result = queryScalar('SELECT id FROM workspaces WHERE id = -1;', z.string());
210
+ await expect(result).rejects.toThrow('Incorrect rowCount: 0');
211
+ });
212
+ it('rejects results with multiple rows', async () => {
213
+ const result = queryScalar('SELECT id FROM workspaces;', z.string());
214
+ await expect(result).rejects.toThrow('Incorrect rowCount: 100');
215
+ });
216
+ it('rejects multi-column queries', async () => {
217
+ const result = queryScalar('SELECT * FROM workspaces WHERE id = 1;', z.string());
218
+ await expect(result).rejects.toThrow('Expected exactly one column');
219
+ });
220
+ });
221
+ describe('queryOptionalScalar', () => {
222
+ it('returns a scalar value when present', async () => {
223
+ const id = await queryOptionalScalar('SELECT id FROM workspaces WHERE id = 1;', z.string());
224
+ assert.equal(id, '1');
225
+ });
226
+ it('handles parameters', async () => {
227
+ const id = await queryOptionalScalar('SELECT id FROM workspaces WHERE id = $1;', [1], z.string());
228
+ assert.equal(id, '1');
229
+ });
230
+ it('returns null for zero rows', async () => {
231
+ const id = await queryOptionalScalar('SELECT id FROM workspaces WHERE id = -1;', z.string());
232
+ assert.isNull(id);
233
+ });
234
+ it('rejects results with multiple rows', async () => {
235
+ const result = queryOptionalScalar('SELECT id FROM workspaces;', z.string());
236
+ await expect(result).rejects.toThrow('Incorrect rowCount: 100');
237
+ });
238
+ it('rejects multi-column queries', async () => {
239
+ const result = queryOptionalScalar('SELECT * FROM workspaces WHERE id = 1;', z.string());
240
+ await expect(result).rejects.toThrow('Expected exactly one column');
241
+ });
242
+ });
243
+ describe('callScalars', () => {
244
+ it('returns all scalar values', async () => {
245
+ const ids = await callScalars('test_sproc_one_column', [10], z.string());
246
+ assert.lengthOf(ids, 10);
247
+ assert.equal(ids[0], '1');
248
+ });
249
+ it('handles no parameters', async () => {
250
+ const ids = await callScalars('test_sproc_one_column_ten_rows', z.string());
251
+ assert.lengthOf(ids, 10);
252
+ });
253
+ it('rejects multi-column sprocs', async () => {
254
+ const result = callScalars('test_sproc_two_columns', [10], z.string());
255
+ await expect(result).rejects.toThrow('Expected exactly one column');
256
+ });
257
+ });
258
+ describe('callScalar', () => {
259
+ it('returns a single scalar value', async () => {
260
+ const id = await callScalar('test_sproc_one_column_one_row', z.string());
261
+ assert.equal(id, '1');
262
+ });
263
+ it('handles parameters', async () => {
264
+ const id = await callScalar('test_sproc_one_column', [1], z.string());
265
+ assert.equal(id, '1');
266
+ });
267
+ it('rejects results with zero rows', async () => {
268
+ const result = callScalar('test_sproc_one_column', [0], z.string());
269
+ await expect(result).rejects.toThrow('Incorrect rowCount: 0');
270
+ });
271
+ it('rejects results with multiple rows', async () => {
272
+ const result = callScalar('test_sproc_one_column', [100], z.string());
273
+ await expect(result).rejects.toThrow('Incorrect rowCount: 100');
274
+ });
275
+ it('rejects multi-column sprocs', async () => {
276
+ const result = callScalar('test_sproc_two_columns', [1], z.string());
277
+ await expect(result).rejects.toThrow('Expected exactly one column');
278
+ });
279
+ });
280
+ describe('callOptionalScalar', () => {
281
+ it('returns a scalar value when present', async () => {
282
+ const id = await callOptionalScalar('test_sproc_one_column_one_row', z.string());
283
+ assert.equal(id, '1');
284
+ });
285
+ it('handles parameters', async () => {
286
+ const id = await callOptionalScalar('test_sproc_one_column', [1], z.string());
287
+ assert.equal(id, '1');
288
+ });
289
+ it('returns null for zero rows', async () => {
290
+ const id = await callOptionalScalar('test_sproc_one_column', [0], z.string());
291
+ assert.isNull(id);
292
+ });
293
+ it('rejects results with multiple rows', async () => {
294
+ const result = callOptionalScalar('test_sproc_one_column', [100], z.string());
295
+ await expect(result).rejects.toThrow('Incorrect rowCount: 100');
296
+ });
297
+ it('rejects multi-column sprocs', async () => {
298
+ const result = callOptionalScalar('test_sproc_two_columns', [1], z.string());
299
+ await expect(result).rejects.toThrow('Expected exactly one column');
300
+ });
301
+ });
183
302
  describe('queryCursor', () => {
184
303
  it('handles single column', async () => {
185
- const cursor = await queryCursor('SELECT id FROM workspaces WHERE id = 1;', z.string());
304
+ const cursor = await queryCursor('SELECT id FROM workspaces WHERE id = 1;', z.object({ id: z.string() }));
186
305
  const allRows = [];
187
306
  for await (const rows of cursor.iterate(10)) {
188
307
  allRows.push(...rows);
189
308
  }
190
- assert.equal(allRows[0], '1');
309
+ assert.equal(allRows[0].id, '1');
191
310
  });
192
311
  it('handles multiple columns', async () => {
193
312
  const cursor = await queryCursor('SELECT * FROM workspaces WHERE id = 1;', WorkspaceSchema);
@@ -1 +1 @@
1
- {"version":3,"file":"pool.test.js","sourceRoot":"","sources":["../src/pool.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Writable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\n\nimport { afterAll, assert, beforeAll, describe, expect, it } from 'vitest';\nimport { ZodError, z } from 'zod';\n\nimport {\n callOptionalRow,\n callRow,\n callRows,\n execute,\n queryAsync,\n queryCursor,\n queryOptionalRow,\n queryRow,\n queryRows,\n} from './default-pool.js';\nimport { makePostgresTestUtils } from './test-utils.js';\n\nconst postgresTestUtils = makePostgresTestUtils({\n database: 'prairielearn_postgres',\n});\n\nconst WorkspaceSchema = z.object({\n id: z.string(),\n created_at: z.date(),\n});\n\nconst SprocTwoColumnsSchema = z.object({\n id: z.string(),\n negative: z.number(),\n});\n\ndescribe('@prairielearn/postgres', function () {\n beforeAll(async () => {\n await postgresTestUtils.createDatabase();\n await execute(\n 'CREATE TABLE workspaces (id BIGSERIAL PRIMARY KEY, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP);',\n );\n await execute('INSERT INTO workspaces (id) SELECT s FROM generate_series(1, 100) AS s');\n await execute(\n 'CREATE FUNCTION test_sproc_one_column(num_entries INT) RETURNS TABLE (id BIGINT) AS $$ BEGIN RETURN QUERY SELECT s::BIGINT AS id FROM generate_series(1, num_entries) AS s; END; $$ LANGUAGE plpgsql;',\n );\n await execute(\n 'CREATE FUNCTION test_sproc_two_columns(num_entries INT) RETURNS TABLE (id BIGINT, negative INT) AS $$ BEGIN RETURN QUERY SELECT s::BIGINT AS id, -s AS negative FROM generate_series(1, num_entries) AS s; END; $$ LANGUAGE plpgsql;',\n );\n await execute(\n 'CREATE FUNCTION test_sproc_one_column_ten_rows() RETURNS TABLE (id BIGINT) AS $$ BEGIN RETURN QUERY SELECT s::BIGINT AS id FROM generate_series(1, 10) AS s; END; $$ LANGUAGE plpgsql;',\n );\n await execute(\n 'CREATE FUNCTION test_sproc_one_column_one_row(OUT id BIGINT) AS $$ BEGIN id = 1; END; $$ LANGUAGE plpgsql;',\n );\n });\n\n afterAll(async () => {\n await postgresTestUtils.dropDatabase();\n });\n\n describe('paramsToArray', () => {\n it('enforces SQL must be a string', async () => {\n // @ts-expect-error SQL must be a string\n const rows = queryAsync({ invalid: true }, {});\n await expect(rows).rejects.toThrow('SQL must be a string');\n });\n\n it('enforces params must be array or object', async () => {\n // @ts-expect-error params must be an array or object\n const rows = queryAsync('SELECT 33;', 33);\n await expect(rows).rejects.toThrow('params must be array or object');\n });\n\n it('rejects missing parameters', async () => {\n const rows = queryAsync('SELECT $missing;', {});\n await expect(rows).rejects.toThrow('Missing parameter');\n });\n\n it('rejects unused parameters in testing', async () => {\n const rows = queryAsync('SELECT 33;', { unsed_parameter: true });\n await expect(rows).rejects.toThrow('Unused parameter');\n });\n });\n\n describe('queryRows', () => {\n it('handles single column', async () => {\n const rows = await queryRows('SELECT id FROM workspaces WHERE id <= 10;', z.string());\n assert.lengthOf(rows, 10);\n assert.equal(rows[0], '1');\n });\n\n it('handles multiple columns', async () => {\n const rows = await queryRows('SELECT * FROM workspaces WHERE id <= 10;', WorkspaceSchema);\n assert.lengthOf(rows, 10);\n assert.equal(rows[0].id, '1');\n assert.isNotNull(rows[0].created_at);\n });\n\n it('handles parameters', async () => {\n const rows = await queryRows(\n 'SELECT * FROM workspaces WHERE id <= $1;',\n [10],\n WorkspaceSchema,\n );\n assert.lengthOf(rows, 10);\n });\n });\n\n describe('queryRow', () => {\n it('handles single column', async () => {\n const row = await queryRow('SELECT id FROM workspaces WHERE id = 1;', z.string());\n assert.equal(row, '1');\n });\n\n it('handles multiple columns', async () => {\n const row = await queryRow('SELECT * FROM workspaces WHERE id = 1;', WorkspaceSchema);\n assert.equal(row.id, '1');\n assert.isNotNull(row.created_at);\n });\n\n it('handles parameters', async () => {\n const row = await queryRow('SELECT * FROM workspaces WHERE id = $1;', [1], WorkspaceSchema);\n assert.equal(row.id, '1');\n });\n\n it('rejects results with zero rows', async () => {\n const rows = queryRow('SELECT * FROM workspaces WHERE id = -1;', WorkspaceSchema);\n await expect(rows).rejects.toThrow('Incorrect rowCount: 0');\n });\n\n it('rejects results with multiple rows', async () => {\n const rows = queryRow('SELECT * FROM workspaces', WorkspaceSchema);\n await expect(rows).rejects.toThrow('Incorrect rowCount: 100');\n });\n });\n\n describe('queryOptionalRow', () => {\n it('handles single column', async () => {\n const row = await queryRow('SELECT id FROM workspaces WHERE id = 1;', z.string());\n assert.equal(row, '1');\n });\n\n it('handles multiple columns', async () => {\n const row = await queryOptionalRow('SELECT * FROM workspaces WHERE id = 1;', WorkspaceSchema);\n assert.isNotNull(row);\n assert.equal(row?.id, '1');\n assert.isNotNull(row?.created_at);\n });\n\n it('handles parameters', async () => {\n const row = await queryOptionalRow(\n 'SELECT * FROM workspaces WHERE id = $1;',\n [1],\n WorkspaceSchema,\n );\n assert.isNotNull(row);\n assert.equal(row?.id, '1');\n });\n\n it('handles missing result', async () => {\n const row = await queryOptionalRow(\n 'SELECT * FROM workspaces WHERE id = -1;',\n WorkspaceSchema,\n );\n assert.isNull(row);\n });\n\n it('rejects with multiple rows', async () => {\n const rows = queryOptionalRow('SELECT * FROM workspaces', WorkspaceSchema);\n await expect(rows).rejects.toThrow('Incorrect rowCount: 100');\n });\n });\n\n describe('callRows', () => {\n it('handles single column', async () => {\n const rows = await callRows('test_sproc_one_column_ten_rows', z.string());\n assert.lengthOf(rows, 10);\n assert.equal(rows[0], '1');\n });\n\n it('handles parameters', async () => {\n const rows = await callRows('test_sproc_one_column', [10], z.string());\n assert.lengthOf(rows, 10);\n assert.equal(rows[0], '1');\n });\n\n it('handles multiple columns', async () => {\n const rows = await callRows('test_sproc_two_columns', [20], SprocTwoColumnsSchema);\n assert.lengthOf(rows, 20);\n assert.equal(rows[0].id, '1');\n assert.equal(rows[0].negative, -1);\n assert.equal(rows[19].id, '20');\n assert.equal(rows[19].negative, -20);\n });\n });\n\n describe('callRow', () => {\n it('handles single column', async () => {\n const row = await callRow('test_sproc_one_column_one_row', z.string());\n assert.equal(row, '1');\n });\n\n it('handles parameters', async () => {\n const row = await callRow('test_sproc_one_column', [1], z.string());\n assert.equal(row, '1');\n });\n\n it('handles multiple columns', async () => {\n const row = await callRow('test_sproc_two_columns', [1], SprocTwoColumnsSchema);\n assert.equal(row.id, '1');\n assert.equal(row.negative, -1);\n });\n\n it('rejects results with zero rows', async () => {\n const row = callRow('test_sproc_two_columns', [0], SprocTwoColumnsSchema);\n await expect(row).rejects.toThrow('Incorrect rowCount: 0');\n });\n\n it('rejects results with multiple rows', async () => {\n const rows = callRow('test_sproc_two_columns', [100], SprocTwoColumnsSchema);\n await expect(rows).rejects.toThrow('Incorrect rowCount: 100');\n });\n });\n\n describe('callOptionalRow', () => {\n it('handles single column', async () => {\n const row = await callOptionalRow('test_sproc_one_column_one_row', z.string());\n assert.equal(row, '1');\n });\n\n it('handles parameters', async () => {\n const row = await callOptionalRow('test_sproc_one_column', [1], z.string());\n assert.equal(row, '1');\n });\n\n it('handles multiple columns', async () => {\n const row = await callOptionalRow('test_sproc_two_columns', [1], SprocTwoColumnsSchema);\n assert.isNotNull(row);\n assert.equal(row?.id, '1');\n assert.equal(row?.negative, -1);\n });\n\n it('handles results with zero rows', async () => {\n const row = await callOptionalRow('test_sproc_two_columns', [0], SprocTwoColumnsSchema);\n assert.isNull(row);\n });\n\n it('rejects results with multiple rows', async () => {\n const rows = callOptionalRow('test_sproc_two_columns', [100], SprocTwoColumnsSchema);\n await expect(rows).rejects.toThrow('Incorrect rowCount: 100');\n });\n });\n\n describe('queryCursor', () => {\n it('handles single column', async () => {\n const cursor = await queryCursor('SELECT id FROM workspaces WHERE id = 1;', z.string());\n const allRows: string[] = [];\n for await (const rows of cursor.iterate(10)) {\n allRows.push(...rows);\n }\n assert.equal(allRows[0], '1');\n });\n\n it('handles multiple columns', async () => {\n const cursor = await queryCursor('SELECT * FROM workspaces WHERE id = 1;', WorkspaceSchema);\n const allRows: z.infer<typeof WorkspaceSchema>[] = [];\n for await (const rows of cursor.iterate(10)) {\n allRows.push(...rows);\n }\n assert.equal(allRows[0].id, '1');\n assert.isNotNull(allRows[0].created_at);\n });\n it('returns zero rows', async () => {\n const cursor = await queryCursor('SELECT * FROM workspaces WHERE id = 10000;', z.unknown());\n const rowBatches = [];\n for await (const rows of cursor.iterate(10)) {\n rowBatches.push(rows);\n }\n assert.lengthOf(rowBatches, 0);\n });\n\n it('returns one row at a time', async () => {\n const cursor = await queryCursor('SELECT * FROM workspaces WHERE id <= 2;', z.unknown());\n const rowBatches = [];\n for await (const rows of cursor.iterate(1)) {\n rowBatches.push(rows);\n }\n assert.lengthOf(rowBatches, 2);\n assert.lengthOf(rowBatches[0], 1);\n assert.lengthOf(rowBatches[1], 1);\n });\n\n it('returns all rows at once', async () => {\n const cursor = queryCursor('SELECT * FROM workspaces WHERE id <= 10;', z.unknown());\n const rowBatches = [];\n for await (const rows of (await cursor).iterate(10)) {\n rowBatches.push(rows);\n }\n assert.lengthOf(rowBatches, 1);\n assert.lengthOf(rowBatches[0], 10);\n });\n\n it('handles errors', async () => {\n const cursor = await queryCursor('NOT VALID SQL', z.unknown());\n\n async function readAllRows() {\n const allRows = [];\n for await (const rows of cursor.iterate(10)) {\n allRows.push(...rows);\n }\n return allRows;\n }\n\n const maybeError = await readAllRows().catch((err) => err);\n assert.instanceOf(maybeError, Error);\n assert.match(maybeError.message, /syntax error/);\n assert.isDefined((maybeError as any).data);\n assert.equal((maybeError as any).data.sql, 'NOT VALID SQL');\n assert.deepEqual((maybeError as any).data.sqlParams, {});\n assert.isDefined((maybeError as any).data.sqlError);\n assert.equal((maybeError as any).data.sqlError.severity, 'ERROR');\n });\n });\n\n describe('queryCursor', () => {\n const WorkspaceSchema = z.object({\n id: z.string(),\n });\n\n const BadWorkspaceSchema = z.object({\n badProperty: z.string(),\n });\n\n describe('iterator', () => {\n it('validates with provided schema', async () => {\n const cursor = await queryCursor(\n 'SELECT * FROM workspaces WHERE id <= 10 ORDER BY id ASC;',\n WorkspaceSchema,\n );\n const allRows = [];\n for await (const rows of cursor.iterate(10)) {\n allRows.push(...rows);\n }\n assert.lengthOf(allRows, 10);\n const workspace = allRows[0] as any;\n assert.equal(workspace.id, '1');\n assert.isUndefined(workspace.state);\n });\n\n it('throws error when validation fails', async () => {\n const cursor = await queryCursor(\n 'SELECT * FROM workspaces WHERE id <= 10 ORDER BY id ASC;',\n BadWorkspaceSchema,\n );\n\n async function readAllRows() {\n const allRows = [];\n for await (const rows of cursor.iterate(10)) {\n allRows.push(...rows);\n }\n return allRows;\n }\n\n const maybeError = await readAllRows().catch((err) => err);\n assert.instanceOf(maybeError, ZodError);\n assert.lengthOf(maybeError.errors, 10);\n });\n });\n\n describe('stream', () => {\n it('validates with provided schema', async () => {\n const cursor = await queryCursor(\n 'SELECT * FROM workspaces WHERE id <= 10 ORDER BY id ASC;',\n WorkspaceSchema,\n );\n const stream = cursor.stream(1);\n const allRows = [];\n for await (const row of stream) {\n allRows.push(row);\n }\n\n assert.lengthOf(allRows, 10);\n });\n\n it('emits an error when validation fails', async () => {\n const cursor = await queryCursor(\n 'SELECT * FROM workspaces ORDER BY id ASC;',\n BadWorkspaceSchema,\n );\n const stream = cursor.stream(1);\n\n async function readAllRows() {\n const allRows = [];\n for await (const row of stream) {\n allRows.push(row);\n }\n return allRows;\n }\n\n const maybeError = await readAllRows().catch((err) => err);\n assert.instanceOf(maybeError, ZodError);\n assert.lengthOf(maybeError.errors, 1);\n });\n\n it('closes the cursor when the stream is closed', async () => {\n const cursor = await queryCursor('SELECT * FROM workspaces;', WorkspaceSchema);\n const stream = cursor.stream(1);\n\n const rows: any[] = [];\n const ac = new AbortController();\n const writable = new Writable({\n objectMode: true,\n write(chunk, _encoding, callback) {\n rows.push(chunk);\n\n // After receiving the first row, abort the stream. This lets us test\n // that the underlying cursor is closed. If it is *not* closed, this\n // `after` hook will fail with a timeout.\n ac.abort();\n callback();\n },\n });\n\n await expect(pipeline(stream, writable, { signal: ac.signal })).rejects.toThrow();\n assert.lengthOf(rows, 1);\n });\n });\n });\n});\n"]}
1
+ {"version":3,"file":"pool.test.js","sourceRoot":"","sources":["../src/pool.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Writable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\n\nimport { afterAll, assert, beforeAll, describe, expect, it } from 'vitest';\nimport { ZodError, z } from 'zod';\n\nimport {\n callOptionalRow,\n callOptionalScalar,\n callRow,\n callRows,\n callScalar,\n callScalars,\n execute,\n queryCursor,\n queryOptionalRow,\n queryOptionalScalar,\n queryRow,\n queryRows,\n queryScalar,\n queryScalars,\n} from './default-pool.js';\nimport { makePostgresTestUtils } from './test-utils.js';\n\nconst postgresTestUtils = makePostgresTestUtils({\n database: 'prairielearn_postgres',\n});\n\nconst WorkspaceSchema = z.object({\n id: z.string(),\n created_at: z.date(),\n});\n\nconst SprocTwoColumnsSchema = z.object({\n id: z.string(),\n negative: z.number(),\n});\n\ndescribe('@prairielearn/postgres', function () {\n beforeAll(async () => {\n await postgresTestUtils.createDatabase();\n await execute(\n 'CREATE TABLE workspaces (id BIGSERIAL PRIMARY KEY, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP);',\n );\n await execute('INSERT INTO workspaces (id) SELECT s FROM generate_series(1, 100) AS s');\n await execute(\n 'CREATE FUNCTION test_sproc_one_column(num_entries INT) RETURNS TABLE (id BIGINT) AS $$ BEGIN RETURN QUERY SELECT s::BIGINT AS id FROM generate_series(1, num_entries) AS s; END; $$ LANGUAGE plpgsql;',\n );\n await execute(\n 'CREATE FUNCTION test_sproc_two_columns(num_entries INT) RETURNS TABLE (id BIGINT, negative INT) AS $$ BEGIN RETURN QUERY SELECT s::BIGINT AS id, -s AS negative FROM generate_series(1, num_entries) AS s; END; $$ LANGUAGE plpgsql;',\n );\n await execute(\n 'CREATE FUNCTION test_sproc_one_column_ten_rows() RETURNS TABLE (id BIGINT) AS $$ BEGIN RETURN QUERY SELECT s::BIGINT AS id FROM generate_series(1, 10) AS s; END; $$ LANGUAGE plpgsql;',\n );\n await execute(\n 'CREATE FUNCTION test_sproc_one_column_one_row(OUT id BIGINT) AS $$ BEGIN id = 1; END; $$ LANGUAGE plpgsql;',\n );\n });\n\n afterAll(async () => {\n await postgresTestUtils.dropDatabase();\n });\n\n describe('paramsToArray', () => {\n it('enforces SQL must be a string', async () => {\n // @ts-expect-error SQL must be a string\n const rows = execute({ invalid: true }, {});\n await expect(rows).rejects.toThrow('SQL must be a string');\n });\n\n it('enforces params must be array or object', async () => {\n // @ts-expect-error params must be an array or object\n const rows = execute('SELECT 33;', 33);\n await expect(rows).rejects.toThrow('params must be array or object');\n });\n\n it('rejects missing parameters', async () => {\n const rows = execute('SELECT $missing;', {});\n await expect(rows).rejects.toThrow('Missing parameter');\n });\n\n it('rejects unused parameters in testing', async () => {\n const rows = execute('SELECT 33;', { unsed_parameter: true });\n await expect(rows).rejects.toThrow('Unused parameter');\n });\n });\n\n describe('queryRows', () => {\n it('handles single column', async () => {\n const rows = await queryRows(\n 'SELECT id FROM workspaces WHERE id <= 10;',\n z.object({ id: z.string() }),\n );\n assert.lengthOf(rows, 10);\n assert.equal(rows[0].id, '1');\n });\n\n it('handles multiple columns', async () => {\n const rows = await queryRows('SELECT * FROM workspaces WHERE id <= 10;', WorkspaceSchema);\n assert.lengthOf(rows, 10);\n assert.equal(rows[0].id, '1');\n assert.isNotNull(rows[0].created_at);\n });\n\n it('handles parameters', async () => {\n const rows = await queryRows(\n 'SELECT * FROM workspaces WHERE id <= $1;',\n [10],\n WorkspaceSchema,\n );\n assert.lengthOf(rows, 10);\n });\n });\n\n describe('queryRow', () => {\n it('handles single column', async () => {\n const row = await queryRow(\n 'SELECT id FROM workspaces WHERE id = 1;',\n z.object({ id: z.string() }),\n );\n assert.equal(row.id, '1');\n });\n\n it('handles multiple columns', async () => {\n const row = await queryRow('SELECT * FROM workspaces WHERE id = 1;', WorkspaceSchema);\n assert.equal(row.id, '1');\n assert.isNotNull(row.created_at);\n });\n\n it('handles parameters', async () => {\n const row = await queryRow('SELECT * FROM workspaces WHERE id = $1;', [1], WorkspaceSchema);\n assert.equal(row.id, '1');\n });\n\n it('rejects results with zero rows', async () => {\n const rows = queryRow('SELECT * FROM workspaces WHERE id = -1;', WorkspaceSchema);\n await expect(rows).rejects.toThrow('Incorrect rowCount: 0');\n });\n\n it('rejects results with multiple rows', async () => {\n const rows = queryRow('SELECT * FROM workspaces', WorkspaceSchema);\n await expect(rows).rejects.toThrow('Incorrect rowCount: 100');\n });\n });\n\n describe('queryOptionalRow', () => {\n it('handles single column', async () => {\n const row = await queryRow(\n 'SELECT id FROM workspaces WHERE id = 1;',\n z.object({ id: z.string() }),\n );\n assert.equal(row.id, '1');\n });\n\n it('handles multiple columns', async () => {\n const row = await queryOptionalRow('SELECT * FROM workspaces WHERE id = 1;', WorkspaceSchema);\n assert.isNotNull(row);\n assert.equal(row?.id, '1');\n assert.isNotNull(row?.created_at);\n });\n\n it('handles parameters', async () => {\n const row = await queryOptionalRow(\n 'SELECT * FROM workspaces WHERE id = $1;',\n [1],\n WorkspaceSchema,\n );\n assert.isNotNull(row);\n assert.equal(row?.id, '1');\n });\n\n it('handles missing result', async () => {\n const row = await queryOptionalRow(\n 'SELECT * FROM workspaces WHERE id = -1;',\n WorkspaceSchema,\n );\n assert.isNull(row);\n });\n\n it('rejects with multiple rows', async () => {\n const rows = queryOptionalRow('SELECT * FROM workspaces', WorkspaceSchema);\n await expect(rows).rejects.toThrow('Incorrect rowCount: 100');\n });\n });\n\n describe('callRows', () => {\n it('handles single column', async () => {\n const rows = await callRows('test_sproc_one_column_ten_rows', z.object({ id: z.string() }));\n assert.lengthOf(rows, 10);\n assert.equal(rows[0].id, '1');\n });\n\n it('handles parameters', async () => {\n const rows = await callRows('test_sproc_one_column', [10], z.object({ id: z.string() }));\n assert.lengthOf(rows, 10);\n assert.equal(rows[0].id, '1');\n });\n\n it('handles multiple columns', async () => {\n const rows = await callRows('test_sproc_two_columns', [20], SprocTwoColumnsSchema);\n assert.lengthOf(rows, 20);\n assert.equal(rows[0].id, '1');\n assert.equal(rows[0].negative, -1);\n assert.equal(rows[19].id, '20');\n assert.equal(rows[19].negative, -20);\n });\n });\n\n describe('callRow', () => {\n it('handles single column', async () => {\n const row = await callRow('test_sproc_one_column_one_row', z.object({ id: z.string() }));\n assert.equal(row.id, '1');\n });\n\n it('handles parameters', async () => {\n const row = await callRow('test_sproc_one_column', [1], z.object({ id: z.string() }));\n assert.equal(row.id, '1');\n });\n\n it('handles multiple columns', async () => {\n const row = await callRow('test_sproc_two_columns', [1], SprocTwoColumnsSchema);\n assert.equal(row.id, '1');\n assert.equal(row.negative, -1);\n });\n\n it('rejects results with zero rows', async () => {\n const row = callRow('test_sproc_two_columns', [0], SprocTwoColumnsSchema);\n await expect(row).rejects.toThrow('Incorrect rowCount: 0');\n });\n\n it('rejects results with multiple rows', async () => {\n const rows = callRow('test_sproc_two_columns', [100], SprocTwoColumnsSchema);\n await expect(rows).rejects.toThrow('Incorrect rowCount: 100');\n });\n });\n\n describe('callOptionalRow', () => {\n it('handles single column', async () => {\n const row = await callOptionalRow(\n 'test_sproc_one_column_one_row',\n z.object({ id: z.string() }),\n );\n assert.equal(row?.id, '1');\n });\n\n it('handles parameters', async () => {\n const row = await callOptionalRow('test_sproc_one_column', [1], z.object({ id: z.string() }));\n assert.equal(row?.id, '1');\n });\n\n it('handles multiple columns', async () => {\n const row = await callOptionalRow('test_sproc_two_columns', [1], SprocTwoColumnsSchema);\n assert.isNotNull(row);\n assert.equal(row?.id, '1');\n assert.equal(row?.negative, -1);\n });\n\n it('handles results with zero rows', async () => {\n const row = await callOptionalRow('test_sproc_two_columns', [0], SprocTwoColumnsSchema);\n assert.isNull(row);\n });\n\n it('rejects results with multiple rows', async () => {\n const rows = callOptionalRow('test_sproc_two_columns', [100], SprocTwoColumnsSchema);\n await expect(rows).rejects.toThrow('Incorrect rowCount: 100');\n });\n });\n\n describe('queryScalars', () => {\n it('returns all scalar values', async () => {\n const ids = await queryScalars(\n 'SELECT id FROM workspaces WHERE id <= 10 ORDER BY id ASC;',\n z.string(),\n );\n assert.lengthOf(ids, 10);\n assert.equal(ids[0], '1');\n assert.equal(ids[9], '10');\n });\n\n it('handles parameters', async () => {\n const ids = await queryScalars(\n 'SELECT id FROM workspaces WHERE id <= $1 ORDER BY id ASC;',\n [5],\n z.string(),\n );\n assert.lengthOf(ids, 5);\n });\n\n it('rejects multi-column queries', async () => {\n const result = queryScalars('SELECT * FROM workspaces WHERE id <= 10;', z.string());\n await expect(result).rejects.toThrow('Expected exactly one column');\n });\n });\n\n describe('queryScalar', () => {\n it('returns a single scalar value', async () => {\n const id = await queryScalar('SELECT id FROM workspaces WHERE id = 1;', z.string());\n assert.equal(id, '1');\n });\n\n it('handles parameters', async () => {\n const id = await queryScalar('SELECT id FROM workspaces WHERE id = $1;', [1], z.string());\n assert.equal(id, '1');\n });\n\n it('rejects results with zero rows', async () => {\n const result = queryScalar('SELECT id FROM workspaces WHERE id = -1;', z.string());\n await expect(result).rejects.toThrow('Incorrect rowCount: 0');\n });\n\n it('rejects results with multiple rows', async () => {\n const result = queryScalar('SELECT id FROM workspaces;', z.string());\n await expect(result).rejects.toThrow('Incorrect rowCount: 100');\n });\n\n it('rejects multi-column queries', async () => {\n const result = queryScalar('SELECT * FROM workspaces WHERE id = 1;', z.string());\n await expect(result).rejects.toThrow('Expected exactly one column');\n });\n });\n\n describe('queryOptionalScalar', () => {\n it('returns a scalar value when present', async () => {\n const id = await queryOptionalScalar('SELECT id FROM workspaces WHERE id = 1;', z.string());\n assert.equal(id, '1');\n });\n\n it('handles parameters', async () => {\n const id = await queryOptionalScalar(\n 'SELECT id FROM workspaces WHERE id = $1;',\n [1],\n z.string(),\n );\n assert.equal(id, '1');\n });\n\n it('returns null for zero rows', async () => {\n const id = await queryOptionalScalar('SELECT id FROM workspaces WHERE id = -1;', z.string());\n assert.isNull(id);\n });\n\n it('rejects results with multiple rows', async () => {\n const result = queryOptionalScalar('SELECT id FROM workspaces;', z.string());\n await expect(result).rejects.toThrow('Incorrect rowCount: 100');\n });\n\n it('rejects multi-column queries', async () => {\n const result = queryOptionalScalar('SELECT * FROM workspaces WHERE id = 1;', z.string());\n await expect(result).rejects.toThrow('Expected exactly one column');\n });\n });\n\n describe('callScalars', () => {\n it('returns all scalar values', async () => {\n const ids = await callScalars('test_sproc_one_column', [10], z.string());\n assert.lengthOf(ids, 10);\n assert.equal(ids[0], '1');\n });\n\n it('handles no parameters', async () => {\n const ids = await callScalars('test_sproc_one_column_ten_rows', z.string());\n assert.lengthOf(ids, 10);\n });\n\n it('rejects multi-column sprocs', async () => {\n const result = callScalars('test_sproc_two_columns', [10], z.string());\n await expect(result).rejects.toThrow('Expected exactly one column');\n });\n });\n\n describe('callScalar', () => {\n it('returns a single scalar value', async () => {\n const id = await callScalar('test_sproc_one_column_one_row', z.string());\n assert.equal(id, '1');\n });\n\n it('handles parameters', async () => {\n const id = await callScalar('test_sproc_one_column', [1], z.string());\n assert.equal(id, '1');\n });\n\n it('rejects results with zero rows', async () => {\n const result = callScalar('test_sproc_one_column', [0], z.string());\n await expect(result).rejects.toThrow('Incorrect rowCount: 0');\n });\n\n it('rejects results with multiple rows', async () => {\n const result = callScalar('test_sproc_one_column', [100], z.string());\n await expect(result).rejects.toThrow('Incorrect rowCount: 100');\n });\n\n it('rejects multi-column sprocs', async () => {\n const result = callScalar('test_sproc_two_columns', [1], z.string());\n await expect(result).rejects.toThrow('Expected exactly one column');\n });\n });\n\n describe('callOptionalScalar', () => {\n it('returns a scalar value when present', async () => {\n const id = await callOptionalScalar('test_sproc_one_column_one_row', z.string());\n assert.equal(id, '1');\n });\n\n it('handles parameters', async () => {\n const id = await callOptionalScalar('test_sproc_one_column', [1], z.string());\n assert.equal(id, '1');\n });\n\n it('returns null for zero rows', async () => {\n const id = await callOptionalScalar('test_sproc_one_column', [0], z.string());\n assert.isNull(id);\n });\n\n it('rejects results with multiple rows', async () => {\n const result = callOptionalScalar('test_sproc_one_column', [100], z.string());\n await expect(result).rejects.toThrow('Incorrect rowCount: 100');\n });\n\n it('rejects multi-column sprocs', async () => {\n const result = callOptionalScalar('test_sproc_two_columns', [1], z.string());\n await expect(result).rejects.toThrow('Expected exactly one column');\n });\n });\n\n describe('queryCursor', () => {\n it('handles single column', async () => {\n const cursor = await queryCursor(\n 'SELECT id FROM workspaces WHERE id = 1;',\n z.object({ id: z.string() }),\n );\n const allRows: { id: string }[] = [];\n for await (const rows of cursor.iterate(10)) {\n allRows.push(...rows);\n }\n assert.equal(allRows[0].id, '1');\n });\n\n it('handles multiple columns', async () => {\n const cursor = await queryCursor('SELECT * FROM workspaces WHERE id = 1;', WorkspaceSchema);\n const allRows: z.infer<typeof WorkspaceSchema>[] = [];\n for await (const rows of cursor.iterate(10)) {\n allRows.push(...rows);\n }\n assert.equal(allRows[0].id, '1');\n assert.isNotNull(allRows[0].created_at);\n });\n it('returns zero rows', async () => {\n const cursor = await queryCursor('SELECT * FROM workspaces WHERE id = 10000;', z.unknown());\n const rowBatches = [];\n for await (const rows of cursor.iterate(10)) {\n rowBatches.push(rows);\n }\n assert.lengthOf(rowBatches, 0);\n });\n\n it('returns one row at a time', async () => {\n const cursor = await queryCursor('SELECT * FROM workspaces WHERE id <= 2;', z.unknown());\n const rowBatches = [];\n for await (const rows of cursor.iterate(1)) {\n rowBatches.push(rows);\n }\n assert.lengthOf(rowBatches, 2);\n assert.lengthOf(rowBatches[0], 1);\n assert.lengthOf(rowBatches[1], 1);\n });\n\n it('returns all rows at once', async () => {\n const cursor = queryCursor('SELECT * FROM workspaces WHERE id <= 10;', z.unknown());\n const rowBatches = [];\n for await (const rows of (await cursor).iterate(10)) {\n rowBatches.push(rows);\n }\n assert.lengthOf(rowBatches, 1);\n assert.lengthOf(rowBatches[0], 10);\n });\n\n it('handles errors', async () => {\n const cursor = await queryCursor('NOT VALID SQL', z.unknown());\n\n async function readAllRows() {\n const allRows = [];\n for await (const rows of cursor.iterate(10)) {\n allRows.push(...rows);\n }\n return allRows;\n }\n\n const maybeError = await readAllRows().catch((err) => err);\n assert.instanceOf(maybeError, Error);\n assert.match(maybeError.message, /syntax error/);\n assert.isDefined((maybeError as any).data);\n assert.equal((maybeError as any).data.sql, 'NOT VALID SQL');\n assert.deepEqual((maybeError as any).data.sqlParams, {});\n assert.isDefined((maybeError as any).data.sqlError);\n assert.equal((maybeError as any).data.sqlError.severity, 'ERROR');\n });\n });\n\n describe('queryCursor', () => {\n const WorkspaceSchema = z.object({\n id: z.string(),\n });\n\n const BadWorkspaceSchema = z.object({\n badProperty: z.string(),\n });\n\n describe('iterator', () => {\n it('validates with provided schema', async () => {\n const cursor = await queryCursor(\n 'SELECT * FROM workspaces WHERE id <= 10 ORDER BY id ASC;',\n WorkspaceSchema,\n );\n const allRows = [];\n for await (const rows of cursor.iterate(10)) {\n allRows.push(...rows);\n }\n assert.lengthOf(allRows, 10);\n const workspace = allRows[0] as any;\n assert.equal(workspace.id, '1');\n assert.isUndefined(workspace.state);\n });\n\n it('throws error when validation fails', async () => {\n const cursor = await queryCursor(\n 'SELECT * FROM workspaces WHERE id <= 10 ORDER BY id ASC;',\n BadWorkspaceSchema,\n );\n\n async function readAllRows() {\n const allRows = [];\n for await (const rows of cursor.iterate(10)) {\n allRows.push(...rows);\n }\n return allRows;\n }\n\n const maybeError = await readAllRows().catch((err) => err);\n assert.instanceOf(maybeError, ZodError);\n assert.lengthOf(maybeError.errors, 10);\n });\n });\n\n describe('stream', () => {\n it('validates with provided schema', async () => {\n const cursor = await queryCursor(\n 'SELECT * FROM workspaces WHERE id <= 10 ORDER BY id ASC;',\n WorkspaceSchema,\n );\n const stream = cursor.stream(1);\n const allRows = [];\n for await (const row of stream) {\n allRows.push(row);\n }\n\n assert.lengthOf(allRows, 10);\n });\n\n it('emits an error when validation fails', async () => {\n const cursor = await queryCursor(\n 'SELECT * FROM workspaces ORDER BY id ASC;',\n BadWorkspaceSchema,\n );\n const stream = cursor.stream(1);\n\n async function readAllRows() {\n const allRows = [];\n for await (const row of stream) {\n allRows.push(row);\n }\n return allRows;\n }\n\n const maybeError = await readAllRows().catch((err) => err);\n assert.instanceOf(maybeError, ZodError);\n assert.lengthOf(maybeError.errors, 1);\n });\n\n it('closes the cursor when the stream is closed', async () => {\n const cursor = await queryCursor('SELECT * FROM workspaces;', WorkspaceSchema);\n const stream = cursor.stream(1);\n\n const rows: any[] = [];\n const ac = new AbortController();\n const writable = new Writable({\n objectMode: true,\n write(chunk, _encoding, callback) {\n rows.push(chunk);\n\n // After receiving the first row, abort the stream. This lets us test\n // that the underlying cursor is closed. If it is *not* closed, this\n // `after` hook will fail with a timeout.\n ac.abort();\n callback();\n },\n });\n\n await expect(pipeline(stream, writable, { signal: ac.signal })).rejects.toThrow();\n assert.lengthOf(rows, 1);\n });\n });\n });\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prairielearn/postgres",
3
- "version": "5.0.2",
3
+ "version": "6.0.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,19 +19,19 @@
19
19
  "dependencies": {
20
20
  "@types/debug": "^4.1.12",
21
21
  "@types/pg-cursor": "^2.7.2",
22
- "es-toolkit": "^1.44.0",
22
+ "es-toolkit": "^1.45.0",
23
23
  "multipipe": "^4.0.0",
24
- "pg": "^8.18.0",
25
- "pg-cursor": "^2.17.0",
26
- "pg-pool": "^3.11.0",
27
- "pg-protocol": "^1.11.0",
24
+ "pg": "^8.19.0",
25
+ "pg-cursor": "^2.18.0",
26
+ "pg-pool": "^3.12.0",
27
+ "pg-protocol": "^1.12.0",
28
28
  "zod": "^3.25.76"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@prairielearn/tsconfig": "^2.0.0",
32
32
  "@types/multipipe": "^3.0.5",
33
- "@types/node": "^24.10.9",
34
- "@typescript/native-preview": "^7.0.0-dev.20260130.1",
33
+ "@types/node": "^24.11.0",
34
+ "@typescript/native-preview": "^7.0.0-dev.20260302.1",
35
35
  "@vitest/coverage-v8": "^4.0.18",
36
36
  "tsx": "^4.21.0",
37
37
  "typescript": "^5.9.3",
@@ -22,6 +22,13 @@ const HIDDEN_PROPERTIES = new Set([
22
22
  'idleCount',
23
23
  'waitingCount',
24
24
  'queryCount',
25
+ // Deprecated methods not re-exported from the default pool
26
+ 'queryAsync',
27
+ 'queryOneRowAsync',
28
+ 'queryZeroOrOneRowAsync',
29
+ 'callAsync',
30
+ 'callOneRowAsync',
31
+ 'callZeroOrOneRowAsync',
25
32
  ]);
26
33
 
27
34
  describe('sqldb', () => {
@@ -69,49 +69,6 @@ export const endTransactionAsync = defaultPool.endTransactionAsync.bind(defaultP
69
69
  * will be committed otherwise.
70
70
  */
71
71
  export const runInTransactionAsync = defaultPool.runInTransactionAsync.bind(defaultPool);
72
- /**
73
- * Executes a query with the specified parameters.
74
- *
75
- * @deprecated Use {@link execute} instead.
76
- *
77
- * Using the return value of this function directly is not recommended. Instead, use
78
- * {@link queryRows}, {@link queryRow}, or {@link queryOptionalRow}.
79
- */
80
- export const queryAsync = defaultPool.queryAsync.bind(defaultPool);
81
- /**
82
- * Executes a query with the specified parameters. Errors if the query does
83
- * not return exactly one row.
84
- *
85
- * @deprecated Use {@link executeRow} or {@link queryRow} instead.
86
- */
87
- export const queryOneRowAsync = defaultPool.queryOneRowAsync.bind(defaultPool);
88
- /**
89
- * Executes a query with the specified parameters. Errors if the query
90
- * returns more than one row.
91
- *
92
- * @deprecated Use {@link queryOptionalRow} instead.
93
- */
94
- export const queryZeroOrOneRowAsync = defaultPool.queryZeroOrOneRowAsync.bind(defaultPool);
95
- /**
96
- * Calls the given sproc with the specified parameters.
97
- *
98
- * @deprecated Use {@link callRows} instead.
99
- */
100
- export const callAsync = defaultPool.callAsync.bind(defaultPool);
101
- /**
102
- * Calls the given sproc with the specified parameters. Errors if the
103
- * sproc does not return exactly one row.
104
- *
105
- * @deprecated Use {@link callRow} instead.
106
- */
107
- export const callOneRowAsync = defaultPool.callOneRowAsync.bind(defaultPool);
108
- /**
109
- * Calls the given sproc with the specified parameters. Errors if the
110
- * sproc returns more than one row.
111
- *
112
- * @deprecated Use {@link callOptionalRow} instead.
113
- */
114
- export const callZeroOrOneRowAsync = defaultPool.callZeroOrOneRowAsync.bind(defaultPool);
115
72
  /**
116
73
  * Calls a sproc with the specified parameters using a specific client.
117
74
  */
@@ -130,21 +87,15 @@ export const callWithClientZeroOrOneRowAsync =
130
87
  /**
131
88
  * Executes a query with the specified parameters. Returns an array of rows
132
89
  * that conform to the given Zod schema.
133
- *
134
- * If the query returns a single column, the return value will be a list of column values.
135
90
  */
136
91
  export const queryRows = defaultPool.queryRows.bind(defaultPool);
137
92
  /**
138
93
  * Executes a query with the specified parameters. Returns exactly one row that conforms to the given Zod schema.
139
- *
140
- * If the query returns a single column, the return value will be the column value itself.
141
94
  */
142
95
  export const queryRow = defaultPool.queryRow.bind(defaultPool);
143
96
  /**
144
97
  * Executes a query with the specified parameters. Returns either null or a
145
98
  * single row that conforms to the given Zod schema, and errors otherwise.
146
- *
147
- * If the query returns a single column, the return value will be the column value itself.
148
99
  */
149
100
  export const queryOptionalRow = defaultPool.queryOptionalRow.bind(defaultPool);
150
101
  /**
@@ -162,6 +113,40 @@ export const callRow = defaultPool.callRow.bind(defaultPool);
162
113
  * or a single row that conforms to the given Zod schema.
163
114
  */
164
115
  export const callOptionalRow = defaultPool.callOptionalRow.bind(defaultPool);
116
+ /**
117
+ * Executes a query and returns all values from a single column, validated
118
+ * against the given Zod schema. Errors if the query returns more than one column.
119
+ */
120
+ export const queryScalars = defaultPool.queryScalars.bind(defaultPool);
121
+ /**
122
+ * Executes a query and returns a single value from a single column, validated
123
+ * against the given Zod schema. Errors if the query does not return exactly
124
+ * one row or returns more than one column.
125
+ */
126
+ export const queryScalar = defaultPool.queryScalar.bind(defaultPool);
127
+ /**
128
+ * Executes a query and returns a single value from a single column, or null
129
+ * if no rows are returned. Validated against the given Zod schema. Errors if
130
+ * the query returns more than one row or more than one column.
131
+ */
132
+ export const queryOptionalScalar = defaultPool.queryOptionalScalar.bind(defaultPool);
133
+ /**
134
+ * Calls the given sproc and returns all values from a single column, validated
135
+ * against the given Zod schema. Errors if the sproc returns more than one column.
136
+ */
137
+ export const callScalars = defaultPool.callScalars.bind(defaultPool);
138
+ /**
139
+ * Calls the given sproc and returns a single value from a single column, validated
140
+ * against the given Zod schema. Errors if the sproc does not return exactly
141
+ * one row or returns more than one column.
142
+ */
143
+ export const callScalar = defaultPool.callScalar.bind(defaultPool);
144
+ /**
145
+ * Calls the given sproc and returns a single value from a single column, or
146
+ * null if no rows are returned. Validated against the given Zod schema.
147
+ * Errors if the sproc returns more than one row or more than one column.
148
+ */
149
+ export const callOptionalScalar = defaultPool.callOptionalScalar.bind(defaultPool);
165
150
 
166
151
  /**
167
152
  * Executes a query with the specified parameters. Returns the number of rows affected.
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { type PoolClient } from 'pg';
2
2
 
3
3
  export { loadSql, loadSqlEquiv } from './loader.js';
4
- export { PostgresPool, type PostgresPoolConfig } from './pool.js';
4
+ export { type AnyRowSchema, PostgresPool, type PostgresPoolConfig } from './pool.js';
5
5
 
6
6
  export * from './default-pool.js';
7
7