rake-db 2.3.30 → 2.3.31
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/package.json +11 -21
- package/.env +0 -1
- package/.env.local +0 -2
- package/.turbo/turbo-check.log +0 -23
- package/.turbo/turbo-test.log +0 -22
- package/.turbo/turbo-test:ci.log +0 -22
- package/CHANGELOG.md +0 -395
- package/app/dbScript.ts +0 -33
- package/app/migrations/20221017181504_createUser.ts +0 -14
- package/app/migrations/20221017200111_createProfile.ts +0 -10
- package/app/migrations/20221017200252_createChat.ts +0 -9
- package/app/migrations/20221017200326_createChatUser.ts +0 -10
- package/app/migrations/20221017200900_createMessage.ts +0 -12
- package/app/migrations/20221017201235_createGeoSchema.ts +0 -5
- package/app/migrations/20221017210011_createCountry.ts +0 -8
- package/app/migrations/20221017210133_createCity.ts +0 -9
- package/app/migrations/20221105202843_createUniqueTable.ts +0 -12
- package/jest-setup.ts +0 -3
- package/rollup.config.js +0 -3
- package/src/ast.ts +0 -130
- package/src/commands/createOrDrop.test.ts +0 -214
- package/src/commands/createOrDrop.ts +0 -151
- package/src/commands/generate.test.ts +0 -136
- package/src/commands/generate.ts +0 -93
- package/src/commands/migrateOrRollback.test.ts +0 -267
- package/src/commands/migrateOrRollback.ts +0 -190
- package/src/common.test.ts +0 -295
- package/src/common.ts +0 -353
- package/src/errors.ts +0 -3
- package/src/index.ts +0 -8
- package/src/migration/change.test.ts +0 -16
- package/src/migration/change.ts +0 -15
- package/src/migration/changeTable.test.ts +0 -897
- package/src/migration/changeTable.ts +0 -566
- package/src/migration/createTable.test.ts +0 -384
- package/src/migration/createTable.ts +0 -193
- package/src/migration/migration.test.ts +0 -430
- package/src/migration/migration.ts +0 -518
- package/src/migration/migrationUtils.ts +0 -307
- package/src/migration/tableMethods.ts +0 -8
- package/src/pull/astToMigration.test.ts +0 -275
- package/src/pull/astToMigration.ts +0 -173
- package/src/pull/dbStructure.test.ts +0 -180
- package/src/pull/dbStructure.ts +0 -413
- package/src/pull/pull.test.ts +0 -115
- package/src/pull/pull.ts +0 -22
- package/src/pull/structureToAst.test.ts +0 -841
- package/src/pull/structureToAst.ts +0 -372
- package/src/rakeDb.test.ts +0 -131
- package/src/rakeDb.ts +0 -84
- package/src/test-utils.ts +0 -64
- package/tsconfig.json +0 -12
package/src/pull/dbStructure.ts
DELETED
|
@@ -1,413 +0,0 @@
|
|
|
1
|
-
import { Adapter } from 'pqb';
|
|
2
|
-
|
|
3
|
-
export namespace DbStructure {
|
|
4
|
-
export type Table = {
|
|
5
|
-
schemaName: string;
|
|
6
|
-
name: string;
|
|
7
|
-
comment?: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type View = {
|
|
11
|
-
schemaName: string;
|
|
12
|
-
name: string;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type Procedure = {
|
|
16
|
-
schemaName: string;
|
|
17
|
-
name: string;
|
|
18
|
-
returnSet: boolean;
|
|
19
|
-
returnType: string;
|
|
20
|
-
kind: string;
|
|
21
|
-
isTrigger: boolean;
|
|
22
|
-
types: string[];
|
|
23
|
-
argTypes: string[];
|
|
24
|
-
argModes: ('i' | 'o')[];
|
|
25
|
-
argNames?: string[];
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export type Column = {
|
|
29
|
-
schemaName: string;
|
|
30
|
-
tableName: string;
|
|
31
|
-
name: string;
|
|
32
|
-
type: string;
|
|
33
|
-
maxChars?: number;
|
|
34
|
-
numericPrecision?: number;
|
|
35
|
-
numericScale?: number;
|
|
36
|
-
dateTimePrecision?: number;
|
|
37
|
-
default?: string;
|
|
38
|
-
isNullable: boolean;
|
|
39
|
-
collation?: string;
|
|
40
|
-
compression?: 'p' | 'l'; // p for pglz, l for lz4
|
|
41
|
-
comment?: string;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export type Index = {
|
|
45
|
-
schemaName: string;
|
|
46
|
-
tableName: string;
|
|
47
|
-
name: string;
|
|
48
|
-
using: string;
|
|
49
|
-
isUnique: boolean;
|
|
50
|
-
columns: (({ column: string } | { expression: string }) & {
|
|
51
|
-
collate?: string;
|
|
52
|
-
opclass?: string;
|
|
53
|
-
order?: string;
|
|
54
|
-
})[];
|
|
55
|
-
include?: string[];
|
|
56
|
-
with?: string;
|
|
57
|
-
tablespace?: string;
|
|
58
|
-
where?: string;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// a = no action, r = restrict, c = cascade, n = set null, d = set default
|
|
62
|
-
type ForeignKeyAction = 'a' | 'r' | 'c' | 'n' | 'd';
|
|
63
|
-
|
|
64
|
-
export type ForeignKey = {
|
|
65
|
-
schemaName: string;
|
|
66
|
-
tableName: string;
|
|
67
|
-
foreignTableSchemaName: string;
|
|
68
|
-
foreignTableName: string;
|
|
69
|
-
name: string;
|
|
70
|
-
columnNames: string[];
|
|
71
|
-
foreignColumnNames: string[];
|
|
72
|
-
match: 'f' | 'p' | 's'; // FULL | PARTIAL | SIMPLE
|
|
73
|
-
onUpdate: ForeignKeyAction;
|
|
74
|
-
onDelete: ForeignKeyAction;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export type PrimaryKey = {
|
|
78
|
-
schemaName: string;
|
|
79
|
-
tableName: string;
|
|
80
|
-
name: string;
|
|
81
|
-
columnNames: string[];
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export type Trigger = {
|
|
85
|
-
schemaName: string;
|
|
86
|
-
tableName: string;
|
|
87
|
-
triggerSchema: string;
|
|
88
|
-
name: string;
|
|
89
|
-
events: string[];
|
|
90
|
-
activation: string;
|
|
91
|
-
condition?: string;
|
|
92
|
-
definition: string;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
export type Extension = {
|
|
96
|
-
schemaName: string;
|
|
97
|
-
name: string;
|
|
98
|
-
version?: string;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export type Enum = {
|
|
102
|
-
schemaName: string;
|
|
103
|
-
name: string;
|
|
104
|
-
values: string[];
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const filterSchema = (table: string) =>
|
|
109
|
-
`${table} !~ '^pg_' AND ${table} != 'information_schema'`;
|
|
110
|
-
|
|
111
|
-
export class DbStructure {
|
|
112
|
-
constructor(private db: Adapter) {}
|
|
113
|
-
|
|
114
|
-
async getSchemas(): Promise<string[]> {
|
|
115
|
-
const { rows } = await this.db.arrays<[string]>(
|
|
116
|
-
`SELECT n.nspname "name"
|
|
117
|
-
FROM pg_catalog.pg_namespace n
|
|
118
|
-
WHERE ${filterSchema('n.nspname')}
|
|
119
|
-
ORDER BY "name"`,
|
|
120
|
-
);
|
|
121
|
-
return rows.flat();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async getTables() {
|
|
125
|
-
const { rows } = await this.db.query<DbStructure.Table>(
|
|
126
|
-
`SELECT
|
|
127
|
-
nspname AS "schemaName",
|
|
128
|
-
relname AS "name",
|
|
129
|
-
obj_description(c.oid) AS comment
|
|
130
|
-
FROM pg_class c
|
|
131
|
-
JOIN pg_catalog.pg_namespace n ON n.oid = relnamespace
|
|
132
|
-
WHERE relkind = 'r'
|
|
133
|
-
AND ${filterSchema('nspname')}
|
|
134
|
-
ORDER BY relname`,
|
|
135
|
-
);
|
|
136
|
-
return rows;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async getViews() {
|
|
140
|
-
const { rows } = await this.db.query<DbStructure.View[]>(
|
|
141
|
-
`SELECT
|
|
142
|
-
table_schema "schemaName",
|
|
143
|
-
table_name "name"
|
|
144
|
-
FROM information_schema.tables
|
|
145
|
-
WHERE table_type = 'VIEW'
|
|
146
|
-
AND ${filterSchema('table_schema')}
|
|
147
|
-
ORDER BY table_name`,
|
|
148
|
-
);
|
|
149
|
-
return rows;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async getProcedures() {
|
|
153
|
-
const { rows } = await this.db.query<DbStructure.Procedure[]>(
|
|
154
|
-
`SELECT
|
|
155
|
-
n.nspname AS "schemaName",
|
|
156
|
-
proname AS name,
|
|
157
|
-
proretset AS "returnSet",
|
|
158
|
-
(
|
|
159
|
-
SELECT typname FROM pg_type WHERE oid = prorettype
|
|
160
|
-
) AS "returnType",
|
|
161
|
-
prokind AS "kind",
|
|
162
|
-
coalesce((
|
|
163
|
-
SELECT true FROM information_schema.triggers
|
|
164
|
-
WHERE n.nspname = trigger_schema AND trigger_name = proname
|
|
165
|
-
LIMIT 1
|
|
166
|
-
), false) AS "isTrigger",
|
|
167
|
-
coalesce((
|
|
168
|
-
SELECT json_agg(pg_type.typname)
|
|
169
|
-
FROM unnest(coalesce(proallargtypes, proargtypes)) typeId
|
|
170
|
-
JOIN pg_type ON pg_type.oid = typeId
|
|
171
|
-
), '[]') AS "types",
|
|
172
|
-
coalesce(to_json(proallargtypes::int[]), to_json(proargtypes::int[])) AS "argTypes",
|
|
173
|
-
coalesce(to_json(proargmodes), '[]') AS "argModes",
|
|
174
|
-
to_json(proargnames) AS "argNames"
|
|
175
|
-
FROM pg_proc p
|
|
176
|
-
JOIN pg_namespace n ON p.pronamespace = n.oid
|
|
177
|
-
WHERE ${filterSchema('n.nspname')}`,
|
|
178
|
-
);
|
|
179
|
-
return rows;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
async getColumns() {
|
|
183
|
-
const { rows } = await this.db.query<DbStructure.Column>(
|
|
184
|
-
`SELECT
|
|
185
|
-
table_schema "schemaName",
|
|
186
|
-
table_name "tableName",
|
|
187
|
-
column_name "name",
|
|
188
|
-
udt_name "type",
|
|
189
|
-
character_maximum_length AS "maxChars",
|
|
190
|
-
numeric_precision AS "numericPrecision",
|
|
191
|
-
numeric_scale AS "numericScale",
|
|
192
|
-
datetime_precision AS "dateTimePrecision",
|
|
193
|
-
column_default "default",
|
|
194
|
-
is_nullable::boolean "isNullable",
|
|
195
|
-
collation_name AS "collation",
|
|
196
|
-
NULLIF(a.attcompression, '') AS compression,
|
|
197
|
-
pgd.description AS "comment"
|
|
198
|
-
FROM information_schema.columns c
|
|
199
|
-
LEFT JOIN pg_catalog.pg_statio_all_tables AS st
|
|
200
|
-
ON c.table_schema = st.schemaname
|
|
201
|
-
AND c.table_name = st.relname
|
|
202
|
-
LEFT JOIN pg_catalog.pg_description pgd
|
|
203
|
-
ON pgd.objoid = st.relid
|
|
204
|
-
AND pgd.objsubid = c.ordinal_position
|
|
205
|
-
LEFT JOIN pg_catalog.pg_attribute a
|
|
206
|
-
ON a.attrelid = st.relid
|
|
207
|
-
AND a.attnum = c.ordinal_position
|
|
208
|
-
WHERE ${filterSchema('table_schema')}
|
|
209
|
-
ORDER BY c.ordinal_position`,
|
|
210
|
-
);
|
|
211
|
-
return rows;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
async getIndexes() {
|
|
215
|
-
const { rows } = await this.db.query<DbStructure.Index>(
|
|
216
|
-
`SELECT
|
|
217
|
-
n.nspname "schemaName",
|
|
218
|
-
t.relname "tableName",
|
|
219
|
-
ic.relname "name",
|
|
220
|
-
am.amname AS "using",
|
|
221
|
-
i.indisunique "isUnique",
|
|
222
|
-
(
|
|
223
|
-
SELECT json_agg(
|
|
224
|
-
(
|
|
225
|
-
CASE WHEN t.e = 0
|
|
226
|
-
THEN jsonb_build_object('expression', pg_get_indexdef(i.indexrelid, t.i::int4, false))
|
|
227
|
-
ELSE jsonb_build_object('column', (
|
|
228
|
-
(
|
|
229
|
-
SELECT attname
|
|
230
|
-
FROM pg_catalog.pg_attribute
|
|
231
|
-
WHERE attrelid = i.indrelid
|
|
232
|
-
AND attnum = t.e
|
|
233
|
-
)
|
|
234
|
-
))
|
|
235
|
-
END
|
|
236
|
-
) || (
|
|
237
|
-
CASE WHEN i.indcollation[t.i - 1] = 0
|
|
238
|
-
THEN '{}'::jsonb
|
|
239
|
-
ELSE (
|
|
240
|
-
SELECT (
|
|
241
|
-
CASE WHEN collname = 'default'
|
|
242
|
-
THEN '{}'::jsonb
|
|
243
|
-
ELSE jsonb_build_object('collate', collname)
|
|
244
|
-
END
|
|
245
|
-
)
|
|
246
|
-
FROM pg_catalog.pg_collation
|
|
247
|
-
WHERE oid = i.indcollation[t.i - 1]
|
|
248
|
-
)
|
|
249
|
-
END
|
|
250
|
-
) || (
|
|
251
|
-
SELECT
|
|
252
|
-
CASE WHEN opcdefault AND attoptions IS NULL
|
|
253
|
-
THEN '{}'::jsonb
|
|
254
|
-
ELSE jsonb_build_object(
|
|
255
|
-
'opclass', opcname || COALESCE('(' || array_to_string(attoptions, ', ') || ')', '')
|
|
256
|
-
)
|
|
257
|
-
END
|
|
258
|
-
FROM pg_opclass
|
|
259
|
-
LEFT JOIN pg_attribute
|
|
260
|
-
ON attrelid = i.indexrelid
|
|
261
|
-
AND attnum = t.i
|
|
262
|
-
WHERE oid = i.indclass[t.i - 1]
|
|
263
|
-
) || (
|
|
264
|
-
CASE WHEN i.indoption[t.i - 1] = 0
|
|
265
|
-
THEN '{}'::jsonb
|
|
266
|
-
ELSE jsonb_build_object(
|
|
267
|
-
'order',
|
|
268
|
-
CASE
|
|
269
|
-
WHEN i.indoption[t.i - 1] = 1 THEN 'DESC NULLS LAST'
|
|
270
|
-
WHEN i.indoption[t.i - 1] = 2 THEN 'ASC NULLS FIRST'
|
|
271
|
-
WHEN i.indoption[t.i - 1] = 3 THEN 'DESC'
|
|
272
|
-
ELSE NULL
|
|
273
|
-
END
|
|
274
|
-
)
|
|
275
|
-
END
|
|
276
|
-
)
|
|
277
|
-
)
|
|
278
|
-
FROM unnest(i.indkey[:indnkeyatts - 1]) WITH ORDINALITY AS t(e, i)
|
|
279
|
-
) "columns",
|
|
280
|
-
(
|
|
281
|
-
SELECT json_agg(
|
|
282
|
-
(
|
|
283
|
-
SELECT attname
|
|
284
|
-
FROM pg_catalog.pg_attribute
|
|
285
|
-
WHERE attrelid = i.indrelid
|
|
286
|
-
AND attnum = j.e
|
|
287
|
-
)
|
|
288
|
-
)
|
|
289
|
-
FROM unnest(i.indkey[indnkeyatts:]) AS j(e)
|
|
290
|
-
) AS "include",
|
|
291
|
-
NULLIF(pg_catalog.array_to_string(
|
|
292
|
-
ic.reloptions || array(SELECT 'toast.' || x FROM pg_catalog.unnest(tc.reloptions) x),
|
|
293
|
-
', '
|
|
294
|
-
), '') AS "with",
|
|
295
|
-
(
|
|
296
|
-
SELECT tablespace
|
|
297
|
-
FROM pg_indexes
|
|
298
|
-
WHERE schemaname = n.nspname
|
|
299
|
-
AND indexname = ic.relname
|
|
300
|
-
) AS tablespace,
|
|
301
|
-
pg_get_expr(i.indpred, i.indrelid) AS "where"
|
|
302
|
-
FROM pg_index i
|
|
303
|
-
JOIN pg_class t ON t.oid = i.indrelid
|
|
304
|
-
JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
305
|
-
JOIN pg_class ic ON ic.oid = i.indexrelid
|
|
306
|
-
JOIN pg_am am ON am.oid = ic.relam
|
|
307
|
-
LEFT JOIN pg_catalog.pg_class tc ON (ic.reltoastrelid = tc.oid)
|
|
308
|
-
WHERE ${filterSchema('n.nspname')}
|
|
309
|
-
AND NOT i.indisprimary
|
|
310
|
-
ORDER BY ic.relname`,
|
|
311
|
-
);
|
|
312
|
-
return rows;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
async getForeignKeys() {
|
|
316
|
-
const { rows } = await this.db.query<DbStructure.ForeignKey>(
|
|
317
|
-
`SELECT
|
|
318
|
-
s.nspname AS "schemaName",
|
|
319
|
-
t.relname AS "tableName",
|
|
320
|
-
fs.nspname AS "foreignTableSchemaName",
|
|
321
|
-
ft.relname AS "foreignTableName",
|
|
322
|
-
c.conname AS "name",
|
|
323
|
-
(
|
|
324
|
-
SELECT json_agg(ccu.column_name)
|
|
325
|
-
FROM information_schema.key_column_usage ccu
|
|
326
|
-
WHERE ccu.constraint_name = c.conname
|
|
327
|
-
AND ccu.table_schema = cs.nspname
|
|
328
|
-
) AS "columnNames",
|
|
329
|
-
(
|
|
330
|
-
SELECT json_agg(ccu.column_name)
|
|
331
|
-
FROM information_schema.constraint_column_usage ccu
|
|
332
|
-
WHERE ccu.constraint_name = c.conname
|
|
333
|
-
AND ccu.table_schema = cs.nspname
|
|
334
|
-
) AS "foreignColumnNames",
|
|
335
|
-
c.confmatchtype AS match,
|
|
336
|
-
c.confupdtype AS "onUpdate",
|
|
337
|
-
c.confdeltype AS "onDelete"
|
|
338
|
-
FROM pg_catalog.pg_constraint c
|
|
339
|
-
JOIN pg_class t ON t.oid = conrelid
|
|
340
|
-
JOIN pg_catalog.pg_namespace s ON s.oid = t.relnamespace
|
|
341
|
-
JOIN pg_class ft ON ft.oid = confrelid
|
|
342
|
-
JOIN pg_catalog.pg_namespace fs ON fs.oid = ft.relnamespace
|
|
343
|
-
JOIN pg_catalog.pg_namespace cs ON cs.oid = c.connamespace
|
|
344
|
-
WHERE contype = 'f'
|
|
345
|
-
ORDER BY c.conname`,
|
|
346
|
-
);
|
|
347
|
-
return rows;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
async getPrimaryKeys() {
|
|
351
|
-
const { rows } = await this.db.query<DbStructure.PrimaryKey>(
|
|
352
|
-
`SELECT tc.table_schema AS "schemaName",
|
|
353
|
-
tc.table_name AS "tableName",
|
|
354
|
-
tc.constraint_name AS "name",
|
|
355
|
-
json_agg(ccu.column_name) "columnNames"
|
|
356
|
-
FROM information_schema.table_constraints tc
|
|
357
|
-
JOIN information_schema.constraint_column_usage ccu
|
|
358
|
-
ON ccu.constraint_name = tc.constraint_name
|
|
359
|
-
AND ccu.table_schema = tc.table_schema
|
|
360
|
-
WHERE tc.constraint_type = 'PRIMARY KEY'
|
|
361
|
-
AND ${filterSchema('tc.table_schema')}
|
|
362
|
-
GROUP BY "schemaName", "tableName", "name"
|
|
363
|
-
ORDER BY "name"`,
|
|
364
|
-
);
|
|
365
|
-
return rows;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
async getTriggers() {
|
|
369
|
-
const { rows } = await this.db.query<DbStructure.Trigger>(
|
|
370
|
-
`SELECT event_object_schema AS "schemaName",
|
|
371
|
-
event_object_table AS "tableName",
|
|
372
|
-
trigger_schema AS "triggerSchema",
|
|
373
|
-
trigger_name AS name,
|
|
374
|
-
json_agg(event_manipulation) AS events,
|
|
375
|
-
action_timing AS activation,
|
|
376
|
-
action_condition AS condition,
|
|
377
|
-
action_statement AS definition
|
|
378
|
-
FROM information_schema.triggers
|
|
379
|
-
WHERE ${filterSchema('event_object_schema')}
|
|
380
|
-
GROUP BY event_object_schema, event_object_table, trigger_schema, trigger_name, action_timing, action_condition, action_statement
|
|
381
|
-
ORDER BY trigger_name`,
|
|
382
|
-
);
|
|
383
|
-
return rows;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
async getExtensions() {
|
|
387
|
-
const { rows } = await this.db.query<DbStructure.Extension>(
|
|
388
|
-
`SELECT
|
|
389
|
-
nspname AS "schemaName",
|
|
390
|
-
extname AS "name",
|
|
391
|
-
extversion AS version
|
|
392
|
-
FROM pg_extension
|
|
393
|
-
JOIN pg_catalog.pg_namespace n ON n.oid = extnamespace
|
|
394
|
-
AND ${filterSchema('n.nspname')}`,
|
|
395
|
-
);
|
|
396
|
-
return rows;
|
|
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
|
-
}
|
|
413
|
-
}
|
package/src/pull/pull.test.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { DbStructure } from './dbStructure';
|
|
2
|
-
import { pullDbStructure } from './pull';
|
|
3
|
-
import { processRakeDbConfig } from '../common';
|
|
4
|
-
import { writeMigrationFile } from '../commands/generate';
|
|
5
|
-
|
|
6
|
-
jest.mock('./dbStructure', () => {
|
|
7
|
-
const { DbStructure } = jest.requireActual('./dbStructure');
|
|
8
|
-
for (const key of Object.getOwnPropertyNames(DbStructure.prototype)) {
|
|
9
|
-
(DbStructure.prototype as unknown as Record<string, () => unknown[]>)[key] =
|
|
10
|
-
() => [];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return { DbStructure };
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
jest.mock('../commands/generate', () => ({
|
|
17
|
-
writeMigrationFile: jest.fn(),
|
|
18
|
-
}));
|
|
19
|
-
|
|
20
|
-
const db = DbStructure.prototype;
|
|
21
|
-
|
|
22
|
-
describe('pull', () => {
|
|
23
|
-
it('should get db structure, convert it to ast, generate migrations', async () => {
|
|
24
|
-
db.getSchemas = async () => ['schema1', 'schema2'];
|
|
25
|
-
db.getTables = async () => [
|
|
26
|
-
{
|
|
27
|
-
schemaName: 'schema',
|
|
28
|
-
name: 'table1',
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
schemaName: 'public',
|
|
32
|
-
name: 'table2',
|
|
33
|
-
},
|
|
34
|
-
];
|
|
35
|
-
db.getPrimaryKeys = async () => [
|
|
36
|
-
{
|
|
37
|
-
schemaName: 'schema',
|
|
38
|
-
tableName: 'table1',
|
|
39
|
-
name: 'table1_pkey',
|
|
40
|
-
columnNames: ['id'],
|
|
41
|
-
},
|
|
42
|
-
];
|
|
43
|
-
db.getColumns = async () => [
|
|
44
|
-
{
|
|
45
|
-
schemaName: 'schema',
|
|
46
|
-
tableName: 'table1',
|
|
47
|
-
name: 'id',
|
|
48
|
-
type: 'int4',
|
|
49
|
-
default: `nextval('table1_id_seq'::regclass)`,
|
|
50
|
-
isNullable: false,
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
schemaName: 'public',
|
|
54
|
-
tableName: 'table2',
|
|
55
|
-
name: 'text',
|
|
56
|
-
type: 'text',
|
|
57
|
-
isNullable: false,
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
schemaName: 'public',
|
|
61
|
-
tableName: 'table2',
|
|
62
|
-
name: 'createdAt',
|
|
63
|
-
type: 'timestamp',
|
|
64
|
-
dateTimePrecision: 6,
|
|
65
|
-
isNullable: false,
|
|
66
|
-
default: 'now()',
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
schemaName: 'public',
|
|
70
|
-
tableName: 'table2',
|
|
71
|
-
name: 'updatedAt',
|
|
72
|
-
type: 'timestamp',
|
|
73
|
-
dateTimePrecision: 6,
|
|
74
|
-
isNullable: false,
|
|
75
|
-
default: 'now()',
|
|
76
|
-
},
|
|
77
|
-
];
|
|
78
|
-
|
|
79
|
-
const config = processRakeDbConfig({
|
|
80
|
-
migrationsPath: 'migrations',
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
await pullDbStructure(
|
|
84
|
-
{
|
|
85
|
-
databaseURL: 'file:path',
|
|
86
|
-
},
|
|
87
|
-
config,
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
expect(writeMigrationFile).toBeCalledWith(
|
|
91
|
-
config,
|
|
92
|
-
'pull',
|
|
93
|
-
`import { change } from 'rake-db';
|
|
94
|
-
|
|
95
|
-
change(async (db) => {
|
|
96
|
-
await db.createSchema('schema1');
|
|
97
|
-
await db.createSchema('schema2');
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
change(async (db) => {
|
|
101
|
-
await db.createTable('schema.table1', (t) => ({
|
|
102
|
-
id: t.serial().primaryKey(),
|
|
103
|
-
}));
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
change(async (db) => {
|
|
107
|
-
await db.createTable('table2', (t) => ({
|
|
108
|
-
text: t.text(),
|
|
109
|
-
...t.timestamps(),
|
|
110
|
-
}));
|
|
111
|
-
});
|
|
112
|
-
`,
|
|
113
|
-
);
|
|
114
|
-
});
|
|
115
|
-
});
|
package/src/pull/pull.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { RakeDbConfig } from '../common';
|
|
2
|
-
import { Adapter, AdapterOptions } from 'pqb';
|
|
3
|
-
import { DbStructure } from './dbStructure';
|
|
4
|
-
import { structureToAst } from './structureToAst';
|
|
5
|
-
import { astToMigration } from './astToMigration';
|
|
6
|
-
import { writeMigrationFile } from '../commands/generate';
|
|
7
|
-
|
|
8
|
-
export const pullDbStructure = async (
|
|
9
|
-
options: AdapterOptions,
|
|
10
|
-
config: RakeDbConfig,
|
|
11
|
-
) => {
|
|
12
|
-
const adapter = new Adapter(options);
|
|
13
|
-
const db = new DbStructure(adapter);
|
|
14
|
-
const ast = await structureToAst(db);
|
|
15
|
-
|
|
16
|
-
await adapter.close();
|
|
17
|
-
|
|
18
|
-
const result = astToMigration(ast);
|
|
19
|
-
if (!result) return;
|
|
20
|
-
|
|
21
|
-
await writeMigrationFile(config, 'pull', result);
|
|
22
|
-
};
|