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.
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +9 -6
- package/dist/index.js +224 -112
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +224 -114
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/migrateOrRollback.test.ts +43 -1
- package/src/commands/migrateOrRollback.ts +13 -15
- package/src/common.ts +16 -0
- package/src/errors.ts +3 -0
- package/src/migration/change.test.ts +16 -0
- package/src/migration/change.ts +5 -16
- package/src/migration/changeTable.test.ts +236 -58
- package/src/migration/changeTable.ts +34 -14
- package/src/migration/createTable.test.ts +31 -7
- package/src/migration/createTable.ts +44 -25
- package/src/migration/migration.test.ts +1 -1
- package/src/migration/migration.ts +6 -8
- package/src/migration/tableMethods.ts +8 -0
- package/src/pull/astToMigration.test.ts +97 -28
- package/src/pull/astToMigration.ts +55 -12
- package/src/pull/dbStructure.test.ts +14 -0
- package/src/pull/dbStructure.ts +21 -0
- package/src/pull/pull.test.ts +4 -0
- package/src/pull/structureToAst.test.ts +37 -0
- package/src/pull/structureToAst.ts +24 -10
- package/src/rakeDb.test.ts +20 -0
- package/src/rakeDb.ts +27 -18
- package/src/test-utils.ts +1 -0
package/src/pull/dbStructure.ts
CHANGED
|
@@ -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
|
}
|
package/src/pull/pull.test.ts
CHANGED
|
@@ -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
|
|
package/src/rakeDb.test.ts
CHANGED
|
@@ -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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|