@dbos-inc/knex-datasource 3.0.8-preview → 3.0.10-preview

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/index.ts CHANGED
@@ -185,6 +185,10 @@ class KnexTransactionHandler implements DataSourceTransactionHandler {
185
185
  }
186
186
  }
187
187
 
188
+ function isKnex(value: Knex | Knex.Config): value is Knex {
189
+ return 'raw' in value;
190
+ }
191
+
188
192
  export class KnexDataSource implements DBOSDataSource<TransactionConfig> {
189
193
  static get client(): Knex.Transaction {
190
194
  if (!DBOS.isInTransaction()) {
@@ -197,13 +201,38 @@ export class KnexDataSource implements DBOSDataSource<TransactionConfig> {
197
201
  return ctx.client;
198
202
  }
199
203
 
200
- static async initializeInternalSchema(config: Knex.Config) {
201
- const knexDB = knex(config);
202
- try {
204
+ static async initializeSchema(knexOrConfig: Knex.Config) {
205
+ if (isKnex(knexOrConfig)) {
206
+ await $initSchema(knexOrConfig);
207
+ } else {
208
+ const knexDB = knex(knexOrConfig);
209
+ try {
210
+ await $initSchema(knexDB);
211
+ } finally {
212
+ await knexDB.destroy();
213
+ }
214
+ }
215
+
216
+ async function $initSchema(knexDB: Knex) {
203
217
  await knexDB.raw(createTransactionCompletionSchemaPG);
204
218
  await knexDB.raw(createTransactionCompletionTablePG);
205
- } finally {
206
- await knexDB.destroy();
219
+ }
220
+ }
221
+
222
+ static async uninitializeSchema(knexOrConfig: Knex.Config) {
223
+ if (isKnex(knexOrConfig)) {
224
+ await $uninitSchema(knexOrConfig);
225
+ } else {
226
+ const knexDB = knex(knexOrConfig);
227
+ try {
228
+ await $uninitSchema(knexDB);
229
+ } finally {
230
+ await knexDB.destroy();
231
+ }
232
+ }
233
+
234
+ async function $uninitSchema(knexDB: Knex) {
235
+ await knexDB.raw('DROP TABLE IF EXISTS dbos.transaction_completion; DROP SCHEMA IF EXISTS dbos;');
207
236
  }
208
237
  }
209
238
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbos-inc/knex-datasource",
3
- "version": "3.0.8-preview",
3
+ "version": "3.0.10-preview",
4
4
  "description": "DBOS DataSource library for Knex ORM with PostgreSQL support",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -1,11 +1,12 @@
1
1
  import { Client } from 'pg';
2
2
  import { KnexDataSource } from '../index';
3
3
  import { dropDB, ensureDB } from './test-helpers';
4
+ import knex from 'knex';
4
5
 
5
- describe('KnexDataSource.configure', () => {
6
+ describe('KnexDataSource.initializeSchema', () => {
6
7
  const config = { user: 'postgres', database: 'knex_ds_config_test' };
7
8
 
8
- beforeAll(async () => {
9
+ beforeEach(async () => {
9
10
  const client = new Client({ ...config, database: 'postgres' });
10
11
  try {
11
12
  await client.connect();
@@ -16,16 +17,55 @@ describe('KnexDataSource.configure', () => {
16
17
  }
17
18
  });
18
19
 
19
- test('configure creates tx outputs table', async () => {
20
- await KnexDataSource.initializeInternalSchema({ client: 'pg', connection: config });
20
+ async function queryTxCompletionTable(client: Client) {
21
+ const result = await client.query(
22
+ 'SELECT workflow_id, function_num, output, error FROM dbos.transaction_completion',
23
+ );
24
+ return result.rowCount;
25
+ }
26
+
27
+ async function txCompletionTableExists(client: Client) {
28
+ const result = await client.query<{ exists: boolean }>(
29
+ "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'dbos' AND table_name = 'transaction_completion');",
30
+ );
31
+ if (result.rowCount !== 1) throw new Error(`unexpected rowcount ${result.rowCount}`);
32
+ return result.rows[0].exists;
33
+ }
34
+
35
+ test('initializeSchema-with-config', async () => {
36
+ const knexConfig = { client: 'pg', connection: config };
37
+ await KnexDataSource.initializeSchema(knexConfig);
21
38
 
22
39
  const client = new Client(config);
23
40
  try {
24
41
  await client.connect();
25
- const result = await client.query('SELECT workflow_id, function_num, output FROM dbos.transaction_completion');
26
- expect(result.rows.length).toBe(0);
42
+ await expect(txCompletionTableExists(client)).resolves.toBe(true);
43
+ await expect(queryTxCompletionTable(client)).resolves.toEqual(0);
44
+
45
+ await KnexDataSource.uninitializeSchema(knexConfig);
46
+
47
+ await expect(txCompletionTableExists(client)).resolves.toBe(false);
48
+ } finally {
49
+ await client.end();
50
+ }
51
+ });
52
+
53
+ test('initializeSchema-with-knex', async () => {
54
+ const knexDB = knex({ client: 'pg', connection: config });
55
+ const client = new Client(config);
56
+ try {
57
+ await KnexDataSource.initializeSchema(knexDB);
58
+ await client.connect();
59
+
60
+ await expect(txCompletionTableExists(client)).resolves.toBe(true);
61
+ await expect(queryTxCompletionTable(client)).resolves.toEqual(0);
62
+
63
+ await KnexDataSource.uninitializeSchema(knexDB);
64
+
65
+ await expect(txCompletionTableExists(client)).resolves.toBe(false);
27
66
  } finally {
28
67
  await client.end();
68
+ await knexDB.destroy();
29
69
  }
30
70
  });
31
71
  });
@@ -43,7 +43,7 @@ describe('KnexDataSource', () => {
43
43
  }
44
44
  }
45
45
 
46
- await KnexDataSource.initializeInternalSchema(config);
46
+ await KnexDataSource.initializeSchema(config);
47
47
  });
48
48
 
49
49
  afterAll(async () => {