rake-db 2.3.26 → 2.3.28

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.
@@ -97,6 +97,12 @@ export namespace DbStructure {
97
97
  name: string;
98
98
  version?: string;
99
99
  };
100
+
101
+ export type Enum = {
102
+ schemaName: string;
103
+ name: string;
104
+ values: string[];
105
+ };
100
106
  }
101
107
 
102
108
  const filterSchema = (table: string) =>
@@ -389,4 +395,19 @@ JOIN pg_catalog.pg_namespace n ON n.oid = extnamespace
389
395
  );
390
396
  return rows;
391
397
  }
398
+
399
+ async getEnums() {
400
+ const { rows } = await this.db.query<DbStructure.Enum>(
401
+ `SELECT
402
+ n.nspname as "schemaName",
403
+ t.typname as name,
404
+ json_agg(e.enumlabel) as values
405
+ FROM pg_type t
406
+ JOIN pg_enum e ON t.oid = e.enumtypid
407
+ JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
408
+ WHERE ${filterSchema('n.nspname')}
409
+ GROUP BY n.nspname, t.typname`,
410
+ );
411
+ return rows;
412
+ }
392
413
  }
@@ -95,11 +95,15 @@ describe('pull', () => {
95
95
  change(async (db) => {
96
96
  await db.createSchema('schema1');
97
97
  await db.createSchema('schema2');
98
+ });
98
99
 
100
+ change(async (db) => {
99
101
  await db.createTable('schema.table1', (t) => ({
100
102
  id: t.serial().primaryKey(),
101
103
  }));
104
+ });
102
105
 
106
+ change(async (db) => {
103
107
  await db.createTable('table2', (t) => ({
104
108
  text: t.text(),
105
109
  ...t.timestamps(),
@@ -99,6 +99,12 @@ const extension: DbStructure.Extension = {
99
99
  version: '123',
100
100
  };
101
101
 
102
+ const enumType: DbStructure.Enum = {
103
+ schemaName: 'public',
104
+ name: 'mood',
105
+ values: ['sad', 'ok', 'happy'],
106
+ };
107
+
102
108
  describe('structureToAst', () => {
103
109
  it('should add schema except public', async () => {
104
110
  const db = new DbStructure(adapter);
@@ -801,4 +807,35 @@ describe('structureToAst', () => {
801
807
  });
802
808
  });
803
809
  });
810
+
811
+ describe('enum', () => {
812
+ it('should add enum', async () => {
813
+ const db = new DbStructure(adapter);
814
+ db.getEnums = async () => [{ ...enumType, schemaName: 'custom' }];
815
+
816
+ const [ast] = (await structureToAst(db)) as [RakeDbAst.Enum];
817
+
818
+ expect(ast).toEqual({
819
+ type: 'enum',
820
+ action: 'create',
821
+ name: 'mood',
822
+ schema: 'custom',
823
+ values: enumType.values,
824
+ });
825
+ });
826
+
827
+ it('should ignore schema if it is `public`', async () => {
828
+ const db = new DbStructure(adapter);
829
+ db.getEnums = async () => [enumType];
830
+
831
+ const [ast] = (await structureToAst(db)) as [RakeDbAst.Enum];
832
+
833
+ expect(ast).toEqual({
834
+ type: 'enum',
835
+ action: 'create',
836
+ name: 'mood',
837
+ values: enumType.values,
838
+ });
839
+ });
840
+ });
804
841
  });
@@ -32,6 +32,7 @@ type Data = {
32
32
  indexes: DbStructure.Index[];
33
33
  foreignKeys: DbStructure.ForeignKey[];
34
34
  extensions: DbStructure.Extension[];
35
+ enums: DbStructure.Enum[];
35
36
  };
36
37
 
37
38
  type PendingTables = Record<
@@ -81,6 +82,26 @@ export const structureToAst = async (db: DbStructure): Promise<RakeDbAst[]> => {
81
82
 
82
83
  const outerFKeys: [DbStructure.ForeignKey, DbStructure.Table][] = [];
83
84
 
85
+ for (const it of data.extensions) {
86
+ ast.push({
87
+ type: 'extension',
88
+ action: 'create',
89
+ name: it.name,
90
+ schema: it.schemaName === 'public' ? undefined : it.schemaName,
91
+ version: it.version,
92
+ });
93
+ }
94
+
95
+ for (const it of data.enums) {
96
+ ast.push({
97
+ type: 'enum',
98
+ action: 'create',
99
+ name: it.name,
100
+ schema: it.schemaName === 'public' ? undefined : it.schemaName,
101
+ values: it.values,
102
+ });
103
+ }
104
+
84
105
  for (const key in pendingTables) {
85
106
  const innerFKeys: DbStructure.ForeignKey[] = [];
86
107
  const { table } = pendingTables[key];
@@ -110,16 +131,6 @@ export const structureToAst = async (db: DbStructure): Promise<RakeDbAst[]> => {
110
131
  });
111
132
  }
112
133
 
113
- for (const it of data.extensions) {
114
- ast.push({
115
- type: 'extension',
116
- action: 'create',
117
- name: it.name,
118
- schema: it.schemaName === 'public' ? undefined : it.schemaName,
119
- version: it.version,
120
- });
121
- }
122
-
123
134
  return ast;
124
135
  };
125
136
 
@@ -132,6 +143,7 @@ const getData = async (db: DbStructure): Promise<Data> => {
132
143
  indexes,
133
144
  foreignKeys,
134
145
  extensions,
146
+ enums,
135
147
  ] = await Promise.all([
136
148
  db.getSchemas(),
137
149
  db.getTables(),
@@ -140,6 +152,7 @@ const getData = async (db: DbStructure): Promise<Data> => {
140
152
  db.getIndexes(),
141
153
  db.getForeignKeys(),
142
154
  db.getExtensions(),
155
+ db.getEnums(),
143
156
  ]);
144
157
 
145
158
  return {
@@ -150,6 +163,7 @@ const getData = async (db: DbStructure): Promise<Data> => {
150
163
  indexes,
151
164
  foreignKeys,
152
165
  extensions,
166
+ enums,
153
167
  };
154
168
  };
155
169
 
@@ -3,6 +3,7 @@ import { createDb, dropDb, resetDb } from './commands/createOrDrop';
3
3
  import { migrate, rollback } from './commands/migrateOrRollback';
4
4
  import { generate } from './commands/generate';
5
5
  import { pullDbStructure } from './pull/pull';
6
+ import { RakeDbError } from './errors';
6
7
 
7
8
  jest.mock('./common', () => ({
8
9
  processRakeDbConfig: (config: unknown) => config,
@@ -108,4 +109,23 @@ describe('rakeDb', () => {
108
109
 
109
110
  expect(log).toBeCalled();
110
111
  });
112
+
113
+ it('should log error and exit process with 1 when RakeDbError thrown', async () => {
114
+ const errorLog = jest.fn();
115
+ const exit = jest.fn(() => undefined as never);
116
+ console.error = errorLog;
117
+ process.exit = exit;
118
+
119
+ const err = new RakeDbError('message');
120
+ const custom = () => {
121
+ throw err;
122
+ };
123
+
124
+ const conf = { ...config, commands: { custom } };
125
+
126
+ await expect(() => rakeDb(options, conf, ['custom'])).rejects.toThrow(err);
127
+
128
+ expect(errorLog).toBeCalledWith('message');
129
+ expect(exit).toBeCalledWith(1);
130
+ });
111
131
  });
package/src/rakeDb.ts CHANGED
@@ -4,6 +4,7 @@ import { migrate, rollback } from './commands/migrateOrRollback';
4
4
  import { processRakeDbConfig, RakeDbConfig } from './common';
5
5
  import { generate } from './commands/generate';
6
6
  import { pullDbStructure } from './pull/pull';
7
+ import { RakeDbError } from './errors';
7
8
 
8
9
  export const rakeDb = async (
9
10
  options: MaybeArray<AdapterOptions>,
@@ -14,24 +15,32 @@ export const rakeDb = async (
14
15
 
15
16
  const command = args[0]?.split(':')[0];
16
17
 
17
- if (command === 'create') {
18
- await createDb(options, config);
19
- } else if (command === 'drop') {
20
- await dropDb(options);
21
- } else if (command === 'reset') {
22
- await resetDb(options, config);
23
- } else if (command === 'migrate') {
24
- await migrate(options, config, args.slice(1));
25
- } else if (command === 'rollback') {
26
- await rollback(options, config, args.slice(1));
27
- } else if (command === 'g' || command === 'generate') {
28
- await generate(config, args.slice(1));
29
- } else if (command === 'pull') {
30
- await pullDbStructure(toArray(options)[0], config);
31
- } else if (config.commands[command]) {
32
- await config.commands[command](toArray(options), config, args.slice(1));
33
- } else {
34
- printHelp();
18
+ try {
19
+ if (command === 'create') {
20
+ await createDb(options, config);
21
+ } else if (command === 'drop') {
22
+ await dropDb(options);
23
+ } else if (command === 'reset') {
24
+ await resetDb(options, config);
25
+ } else if (command === 'migrate') {
26
+ await migrate(options, config, args.slice(1));
27
+ } else if (command === 'rollback') {
28
+ await rollback(options, config, args.slice(1));
29
+ } else if (command === 'g' || command === 'generate') {
30
+ await generate(config, args.slice(1));
31
+ } else if (command === 'pull') {
32
+ await pullDbStructure(toArray(options)[0], config);
33
+ } else if (config.commands[command]) {
34
+ await config.commands[command](toArray(options), config, args.slice(1));
35
+ } else {
36
+ printHelp();
37
+ }
38
+ } catch (err) {
39
+ if (err instanceof RakeDbError) {
40
+ console.error(err.message);
41
+ process.exit(1);
42
+ }
43
+ throw err;
35
44
  }
36
45
  };
37
46
 
package/src/test-utils.ts CHANGED
@@ -24,6 +24,7 @@ export const getDb = () => {
24
24
  {},
25
25
  );
26
26
  db.adapter.query = queryMock;
27
+ db.adapter.arrays = queryMock;
27
28
  return db;
28
29
  };
29
30