rake-db 2.3.30 → 2.3.32

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.
Files changed (57) hide show
  1. package/dist/index.d.ts +10 -22
  2. package/dist/index.js +6 -6
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +6 -6
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +12 -22
  7. package/.env +0 -1
  8. package/.env.local +0 -2
  9. package/.turbo/turbo-check.log +0 -23
  10. package/.turbo/turbo-test.log +0 -22
  11. package/.turbo/turbo-test:ci.log +0 -22
  12. package/CHANGELOG.md +0 -395
  13. package/app/dbScript.ts +0 -33
  14. package/app/migrations/20221017181504_createUser.ts +0 -14
  15. package/app/migrations/20221017200111_createProfile.ts +0 -10
  16. package/app/migrations/20221017200252_createChat.ts +0 -9
  17. package/app/migrations/20221017200326_createChatUser.ts +0 -10
  18. package/app/migrations/20221017200900_createMessage.ts +0 -12
  19. package/app/migrations/20221017201235_createGeoSchema.ts +0 -5
  20. package/app/migrations/20221017210011_createCountry.ts +0 -8
  21. package/app/migrations/20221017210133_createCity.ts +0 -9
  22. package/app/migrations/20221105202843_createUniqueTable.ts +0 -12
  23. package/jest-setup.ts +0 -3
  24. package/rollup.config.js +0 -3
  25. package/src/ast.ts +0 -130
  26. package/src/commands/createOrDrop.test.ts +0 -214
  27. package/src/commands/createOrDrop.ts +0 -151
  28. package/src/commands/generate.test.ts +0 -136
  29. package/src/commands/generate.ts +0 -93
  30. package/src/commands/migrateOrRollback.test.ts +0 -267
  31. package/src/commands/migrateOrRollback.ts +0 -190
  32. package/src/common.test.ts +0 -295
  33. package/src/common.ts +0 -353
  34. package/src/errors.ts +0 -3
  35. package/src/index.ts +0 -8
  36. package/src/migration/change.test.ts +0 -16
  37. package/src/migration/change.ts +0 -15
  38. package/src/migration/changeTable.test.ts +0 -897
  39. package/src/migration/changeTable.ts +0 -566
  40. package/src/migration/createTable.test.ts +0 -384
  41. package/src/migration/createTable.ts +0 -193
  42. package/src/migration/migration.test.ts +0 -430
  43. package/src/migration/migration.ts +0 -518
  44. package/src/migration/migrationUtils.ts +0 -307
  45. package/src/migration/tableMethods.ts +0 -8
  46. package/src/pull/astToMigration.test.ts +0 -275
  47. package/src/pull/astToMigration.ts +0 -173
  48. package/src/pull/dbStructure.test.ts +0 -180
  49. package/src/pull/dbStructure.ts +0 -413
  50. package/src/pull/pull.test.ts +0 -115
  51. package/src/pull/pull.ts +0 -22
  52. package/src/pull/structureToAst.test.ts +0 -841
  53. package/src/pull/structureToAst.ts +0 -372
  54. package/src/rakeDb.test.ts +0 -131
  55. package/src/rakeDb.ts +0 -84
  56. package/src/test-utils.ts +0 -64
  57. package/tsconfig.json +0 -12
@@ -1,307 +0,0 @@
1
- import {
2
- ColumnType,
3
- ForeignKeyTable,
4
- ForeignKeyOptions,
5
- getRaw,
6
- isRaw,
7
- quote,
8
- Sql,
9
- TableData,
10
- toArray,
11
- } from 'pqb';
12
- import { ColumnComment, Migration } from './migration';
13
- import {
14
- getSchemaAndTableFromName,
15
- joinColumns,
16
- quoteWithSchema,
17
- } from '../common';
18
-
19
- export const columnToSql = (
20
- key: string,
21
- item: ColumnType,
22
- values: unknown[],
23
- hasMultiplePrimaryKeys: boolean,
24
- ): string => {
25
- const line = [`"${key}" ${item.toSQL()}`];
26
-
27
- if (item.data.compression) {
28
- line.push(`COMPRESSION ${item.data.compression}`);
29
- }
30
-
31
- if (item.data.collate) {
32
- line.push(`COLLATE ${quote(item.data.collate)}`);
33
- }
34
-
35
- if (item.isPrimaryKey && !hasMultiplePrimaryKeys) {
36
- line.push('PRIMARY KEY');
37
- } else if (!item.data.isNullable) {
38
- line.push('NOT NULL');
39
- }
40
-
41
- if (item.data.default !== undefined) {
42
- if (
43
- typeof item.data.default === 'object' &&
44
- item.data.default &&
45
- isRaw(item.data.default)
46
- ) {
47
- line.push(`DEFAULT ${getRaw(item.data.default, values)}`);
48
- } else {
49
- line.push(`DEFAULT ${quote(item.data.default)}`);
50
- }
51
- }
52
-
53
- const { foreignKeys } = item.data;
54
- if (foreignKeys) {
55
- for (const foreignKey of foreignKeys) {
56
- const [schema, table] = getForeignKeyTable(
57
- 'fn' in foreignKey ? foreignKey.fn : foreignKey.table,
58
- );
59
-
60
- if (foreignKey.name) {
61
- line.push(`CONSTRAINT "${foreignKey.name}"`);
62
- }
63
-
64
- line.push(referencesToSql(schema, table, foreignKey.columns, foreignKey));
65
- }
66
- }
67
-
68
- return line.join(' ');
69
- };
70
-
71
- export const addColumnIndex = (
72
- indexes: TableData.Index[],
73
- key: string,
74
- item: ColumnType,
75
- ) => {
76
- if (item.data.indexes) {
77
- indexes.push(
78
- ...item.data.indexes.map((index) => ({
79
- columns: [{ ...index, column: key }],
80
- options: index,
81
- })),
82
- );
83
- }
84
- };
85
-
86
- export const addColumnComment = (
87
- comments: ColumnComment[],
88
- key: string,
89
- item: ColumnType,
90
- ) => {
91
- if (item.data.comment) {
92
- comments.push({ column: key, comment: item.data.comment });
93
- }
94
- };
95
-
96
- export const getForeignKeyTable = (
97
- fnOrTable: (() => ForeignKeyTable) | string,
98
- ): [string | undefined, string] => {
99
- if (typeof fnOrTable === 'string') {
100
- return getSchemaAndTableFromName(fnOrTable);
101
- }
102
-
103
- const item = new (fnOrTable())();
104
- return [item.schema, item.table];
105
- };
106
-
107
- export const getForeignKeyName = (table: string, columns: string[]) => {
108
- return `${table}_${columns.join('_')}_fkey`;
109
- };
110
-
111
- export const constraintToSql = (
112
- { name }: { schema?: string; name: string },
113
- up: boolean,
114
- foreignKey: TableData['foreignKeys'][number],
115
- ) => {
116
- const constraintName =
117
- foreignKey.options.name || getForeignKeyName(name, foreignKey.columns);
118
-
119
- if (!up) {
120
- const { dropMode } = foreignKey.options;
121
- return `CONSTRAINT "${constraintName}"${dropMode ? ` ${dropMode}` : ''}`;
122
- }
123
-
124
- const [schema, table] = getForeignKeyTable(foreignKey.fnOrTable);
125
- return `CONSTRAINT "${constraintName}" FOREIGN KEY (${joinColumns(
126
- foreignKey.columns,
127
- )}) ${referencesToSql(
128
- schema,
129
- table,
130
- foreignKey.foreignColumns,
131
- foreignKey.options,
132
- )}`;
133
- };
134
-
135
- export const referencesToSql = (
136
- schema: string | undefined,
137
- table: string,
138
- columns: string[],
139
- foreignKey: Pick<ForeignKeyOptions, 'match' | 'onDelete' | 'onUpdate'>,
140
- ) => {
141
- const sql: string[] = [
142
- `REFERENCES ${quoteWithSchema({ schema, name: table })}(${joinColumns(
143
- columns,
144
- )})`,
145
- ];
146
-
147
- if (foreignKey.match) {
148
- sql.push(`MATCH ${foreignKey.match.toUpperCase()}`);
149
- }
150
-
151
- if (foreignKey.onDelete) {
152
- sql.push(`ON DELETE ${foreignKey.onDelete.toUpperCase()}`);
153
- }
154
-
155
- if (foreignKey.onUpdate) {
156
- sql.push(`ON UPDATE ${foreignKey.onUpdate.toUpperCase()}`);
157
- }
158
-
159
- return sql.join(' ');
160
- };
161
-
162
- export const getIndexName = (
163
- table: string,
164
- columns: TableData.Index['columns'],
165
- ) => {
166
- return `${table}_${columns
167
- .map((it) =>
168
- 'column' in it
169
- ? it.column
170
- : it.expression.match(/\w+/g)?.join('_') || 'expression',
171
- )
172
- .join('_')}_idx`;
173
- };
174
-
175
- export const indexesToQuery = (
176
- up: boolean,
177
- { schema, name }: { schema?: string; name: string },
178
- indexes: TableData.Index[],
179
- ): Sql[] => {
180
- return indexes.map(({ columns, options }) => {
181
- const indexName = options.name || getIndexName(name, columns);
182
-
183
- if (!up) {
184
- return {
185
- text: `DROP INDEX "${indexName}"${
186
- options.dropMode ? ` ${options.dropMode}` : ''
187
- }`,
188
- values: [],
189
- };
190
- }
191
-
192
- const values: unknown[] = [];
193
-
194
- const sql: string[] = ['CREATE'];
195
-
196
- if (options.unique) {
197
- sql.push('UNIQUE');
198
- }
199
-
200
- sql.push(`INDEX "${indexName}" ON ${quoteWithSchema({ schema, name })}`);
201
-
202
- if (options.using) {
203
- sql.push(`USING ${options.using}`);
204
- }
205
-
206
- const columnsSql: string[] = [];
207
-
208
- columns.forEach((column) => {
209
- const columnSql: string[] = [
210
- 'column' in column ? `"${column.column}"` : `(${column.expression})`,
211
- ];
212
-
213
- if (column.collate) {
214
- columnSql.push(`COLLATE '${column.collate}'`);
215
- }
216
-
217
- if (column.opclass) {
218
- columnSql.push(column.opclass);
219
- }
220
-
221
- if (column.order) {
222
- columnSql.push(column.order);
223
- }
224
-
225
- columnsSql.push(columnSql.join(' '));
226
- });
227
-
228
- sql.push(`(${columnsSql.join(', ')})`);
229
-
230
- if (options.include) {
231
- sql.push(
232
- `INCLUDE (${toArray(options.include)
233
- .map((column) => `"${column}"`)
234
- .join(', ')})`,
235
- );
236
- }
237
-
238
- if (options.with) {
239
- sql.push(`WITH (${options.with})`);
240
- }
241
-
242
- if (options.tablespace) {
243
- sql.push(`TABLESPACE ${options.tablespace}`);
244
- }
245
-
246
- if (options.where) {
247
- sql.push(
248
- `WHERE ${
249
- typeof options.where === 'object' &&
250
- options.where &&
251
- isRaw(options.where)
252
- ? getRaw(options.where, values)
253
- : options.where
254
- }`,
255
- );
256
- }
257
-
258
- return { text: sql.join(' '), values };
259
- });
260
- };
261
-
262
- export const commentsToQuery = (
263
- schemaTable: { schema?: string; name: string },
264
- comments: ColumnComment[],
265
- ): Sql[] => {
266
- return comments.map(({ column, comment }) => ({
267
- text: `COMMENT ON COLUMN ${quoteWithSchema(
268
- schemaTable,
269
- )}."${column}" IS ${quote(comment)}`,
270
- values: [],
271
- }));
272
- };
273
-
274
- export const primaryKeyToSql = (
275
- primaryKey: Exclude<TableData['primaryKey'], undefined>,
276
- ) => {
277
- const name = primaryKey.options?.name;
278
- return `${name ? `CONSTRAINT "${name}" ` : ''}PRIMARY KEY (${joinColumns(
279
- primaryKey.columns,
280
- )})`;
281
- };
282
-
283
- export const getPrimaryKeysOfTable = async (
284
- db: Migration,
285
- tableName: string,
286
- ): Promise<{ name: string; type: string }[]> => {
287
- const { rows } = await db.adapter.query<{ name: string; type: string }>(
288
- {
289
- text: `SELECT
290
- pg_attribute.attname AS name,
291
- format_type(pg_attribute.atttypid, pg_attribute.atttypmod) AS type
292
- FROM pg_index, pg_class, pg_attribute, pg_namespace
293
- WHERE
294
- pg_class.oid = $1::regclass AND
295
- indrelid = pg_class.oid AND
296
- nspname = 'public' AND
297
- pg_class.relnamespace = pg_namespace.oid AND
298
- pg_attribute.attrelid = pg_class.oid AND
299
- pg_attribute.attnum = any(pg_index.indkey) AND
300
- indisprimary`,
301
- values: [tableName],
302
- },
303
- db.adapter.types,
304
- );
305
-
306
- return rows;
307
- };
@@ -1,8 +0,0 @@
1
- import { EnumColumn, raw } from 'pqb';
2
-
3
- export const tableMethods = {
4
- raw,
5
- enum: (name: string) =>
6
- // empty array will be filled during the migration by querying db
7
- new EnumColumn(name, [] as unknown as [string, ...string[]]),
8
- };
@@ -1,275 +0,0 @@
1
- import { astToMigration } from './astToMigration';
2
- import { columnTypes } from 'pqb';
3
- import { RakeDbAst } from '../ast';
4
-
5
- const template = (content: string) => `import { change } from 'rake-db';
6
-
7
- change(async (db) => {
8
- ${content}
9
- });
10
- `;
11
-
12
- const schema: RakeDbAst.Schema = {
13
- type: 'schema',
14
- action: 'create',
15
- name: 'schemaName',
16
- };
17
-
18
- const extension: RakeDbAst.Extension = {
19
- type: 'extension',
20
- action: 'create',
21
- name: 'extensionName',
22
- };
23
-
24
- const enumType: RakeDbAst.Enum = {
25
- type: 'enum',
26
- action: 'create',
27
- name: 'mood',
28
- values: ['sad', 'ok', 'happy'],
29
- };
30
-
31
- const table: RakeDbAst.Table = {
32
- type: 'table',
33
- action: 'create',
34
- schema: 'schema',
35
- name: 'table',
36
- noPrimaryKey: 'ignore',
37
- indexes: [],
38
- foreignKeys: [],
39
- shape: {
40
- id: columnTypes.serial().primaryKey(),
41
- },
42
- };
43
-
44
- const foreignKey: RakeDbAst.ForeignKey = {
45
- type: 'foreignKey',
46
- action: 'create',
47
- tableName: 'table',
48
- columns: ['otherId'],
49
- fnOrTable: 'otherTable',
50
- foreignColumns: ['id'],
51
- options: {},
52
- };
53
-
54
- describe('astToMigration', () => {
55
- beforeEach(jest.clearAllMocks);
56
-
57
- it('should return undefined when ast is empty', () => {
58
- const result = astToMigration([]);
59
-
60
- expect(result).toBe(undefined);
61
- });
62
-
63
- it('should put schema, extension, enum to first change, tables to separate changes, foreignKeys in last change', () => {
64
- const result = astToMigration([
65
- schema,
66
- extension,
67
- enumType,
68
- table,
69
- { ...table, name: 'other' },
70
- foreignKey,
71
- ]);
72
-
73
- expect(result).toBe(`import { change } from 'rake-db';
74
-
75
- change(async (db) => {
76
- await db.createSchema('schemaName');
77
-
78
- await db.createExtension('extensionName');
79
-
80
- await db.createEnum('mood', ['sad', 'ok', 'happy']);
81
- });
82
-
83
- change(async (db) => {
84
- await db.createTable('schema.table', (t) => ({
85
- id: t.serial().primaryKey(),
86
- }));
87
- });
88
-
89
- change(async (db) => {
90
- await db.createTable('schema.other', (t) => ({
91
- id: t.serial().primaryKey(),
92
- }));
93
- });
94
-
95
- change(async (db) => {
96
- await db.addForeignKey(
97
- 'table',
98
- ['otherId'],
99
- 'otherTable',
100
- ['id'],
101
- );
102
- });
103
- `);
104
- });
105
-
106
- it('should create schema', () => {
107
- const result = astToMigration([schema]);
108
-
109
- expect(result).toBe(template(` await db.createSchema('schemaName');`));
110
- });
111
-
112
- it('should create extension', () => {
113
- const result = astToMigration([
114
- {
115
- ...extension,
116
- schema: 'schema',
117
- version: '123',
118
- },
119
- ]);
120
-
121
- expect(result).toBe(
122
- template(` await db.createExtension('extensionName', {
123
- schema: 'schema',
124
- version: '123',
125
- });`),
126
- );
127
- });
128
-
129
- it('should create enum', () => {
130
- const result = astToMigration([
131
- {
132
- ...enumType,
133
- schema: 'schema',
134
- },
135
- ]);
136
-
137
- expect(result).toBe(
138
- template(` await db.createEnum('mood', ['sad', 'ok', 'happy'], {
139
- schema: 'schema',
140
- });`),
141
- );
142
- });
143
-
144
- describe('table', () => {
145
- it('should create table', () => {
146
- const result = astToMigration([table]);
147
-
148
- expect(result).toBe(
149
- template(` await db.createTable('schema.table', (t) => ({
150
- id: t.serial().primaryKey(),
151
- }));`),
152
- );
153
- });
154
-
155
- it('should add columns with indexes and foreignKeys', () => {
156
- const result = astToMigration([
157
- {
158
- ...table,
159
- shape: {
160
- someId: columnTypes
161
- .integer()
162
- .unique({ name: 'indexName' })
163
- .foreignKey('otherTable', 'otherId', {
164
- name: 'fkey',
165
- match: 'FULL',
166
- onUpdate: 'CASCADE',
167
- onDelete: 'CASCADE',
168
- }),
169
- },
170
- },
171
- ]);
172
-
173
- expect(result).toBe(`import { change } from 'rake-db';
174
-
175
- change(async (db) => {
176
- await db.createTable('schema.table', (t) => ({
177
- someId: t.integer().foreignKey('otherTable', 'otherId', {
178
- name: 'fkey',
179
- match: 'FULL',
180
- onUpdate: 'CASCADE',
181
- onDelete: 'CASCADE',
182
- }).unique({
183
- name: 'indexName',
184
- }),
185
- }));
186
- });
187
- `);
188
- });
189
-
190
- it('should add composite primaryKeys, indexes, foreignKeys', () => {
191
- const result = astToMigration([
192
- {
193
- ...table,
194
- shape: {
195
- id: columnTypes.serial().primaryKey(),
196
- },
197
- primaryKey: { columns: ['id', 'name'], options: { name: 'pkey' } },
198
- indexes: [
199
- {
200
- columns: [{ column: 'id' }, { column: 'name' }],
201
- options: { name: 'index', unique: true },
202
- },
203
- ],
204
- foreignKeys: [
205
- {
206
- columns: ['id', 'name'],
207
- fnOrTable: 'otherTable',
208
- foreignColumns: ['otherId', 'otherName'],
209
- options: {
210
- name: 'fkey',
211
- match: 'FULL',
212
- onUpdate: 'CASCADE',
213
- onDelete: 'CASCADE',
214
- },
215
- },
216
- ],
217
- },
218
- ]);
219
-
220
- expect(result).toBe(
221
- template(` await db.createTable('schema.table', (t) => ({
222
- id: t.serial().primaryKey(),
223
- ...t.primaryKey(['id', 'name'], { name: 'pkey' }),
224
- ...t.index(['id', 'name'], {
225
- name: 'index',
226
- unique: true,
227
- }),
228
- ...t.foreignKey(
229
- ['id', 'name'],
230
- 'otherTable',
231
- ['otherId', 'otherName'],
232
- {
233
- name: 'fkey',
234
- match: 'FULL',
235
- onUpdate: 'CASCADE',
236
- onDelete: 'CASCADE',
237
- },
238
- ),
239
- }));`),
240
- );
241
- });
242
- });
243
-
244
- describe('foreignKey', () => {
245
- it('should add standalone foreignKey', () => {
246
- const result = astToMigration([
247
- {
248
- ...foreignKey,
249
- tableSchema: 'custom',
250
- options: {
251
- name: 'fkey',
252
- match: 'FULL',
253
- onUpdate: 'CASCADE',
254
- onDelete: 'CASCADE',
255
- },
256
- },
257
- ]);
258
-
259
- expect(result).toBe(
260
- template(` await db.addForeignKey(
261
- 'custom.table',
262
- ['otherId'],
263
- 'otherTable',
264
- ['id'],
265
- {
266
- name: 'fkey',
267
- match: 'FULL',
268
- onUpdate: 'CASCADE',
269
- onDelete: 'CASCADE',
270
- },
271
- );`),
272
- );
273
- });
274
- });
275
- });