rake-db 2.2.6 → 2.3.0

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.
@@ -78,9 +78,8 @@ describe('changeTable', () => {
78
78
  name: 'indexName',
79
79
  unique: true,
80
80
  using: 'gin',
81
- expression: 10,
82
81
  collate: 'utf-8',
83
- operator: 'operator',
82
+ opclass: 'opclass',
84
83
  order: 'ASC',
85
84
  include: 'id',
86
85
  with: 'fillfactor = 70',
@@ -133,7 +132,7 @@ describe('changeTable', () => {
133
132
  CREATE UNIQUE INDEX "indexName"
134
133
  ON "table"
135
134
  USING gin
136
- ("withIndex"(10) COLLATE 'utf-8' operator ASC)
135
+ ("withIndex" COLLATE 'utf-8' opclass ASC)
137
136
  INCLUDE ("id")
138
137
  WITH (fillfactor = 70)
139
138
  TABLESPACE tablespace
@@ -604,9 +603,8 @@ describe('changeTable', () => {
604
603
  addIndexWithOptions: t.change(
605
604
  t.integer(),
606
605
  t.integer().index({
607
- expression: 'expression',
608
606
  collate: 'collate',
609
- operator: 'operator',
607
+ opclass: 'opclass',
610
608
  order: 'order',
611
609
  unique: true,
612
610
  using: 'using',
@@ -620,9 +618,8 @@ describe('changeTable', () => {
620
618
  removeIndex: t.change(t.integer().index(), t.integer()),
621
619
  removeIndexWithOptions: t.change(
622
620
  t.integer().index({
623
- expression: 'expression',
624
621
  collate: 'collate',
625
- operator: 'operator',
622
+ opclass: 'opclass',
626
623
  order: 'order',
627
624
  unique: true,
628
625
  using: 'using',
@@ -637,9 +634,8 @@ describe('changeTable', () => {
637
634
  changeIndex: t.change(
638
635
  t.integer().index({
639
636
  name: 'from',
640
- expression: 'from',
641
637
  collate: 'from',
642
- operator: 'from',
638
+ opclass: 'from',
643
639
  order: 'from',
644
640
  unique: false,
645
641
  using: 'from',
@@ -651,9 +647,8 @@ describe('changeTable', () => {
651
647
  }),
652
648
  t.integer().index({
653
649
  name: 'to',
654
- expression: 'to',
655
650
  collate: 'to',
656
- operator: 'to',
651
+ opclass: 'to',
657
652
  order: 'to',
658
653
  unique: true,
659
654
  using: 'to',
@@ -673,8 +668,8 @@ describe('changeTable', () => {
673
668
  `DROP INDEX "tableRemoveIndexWithOptionsIndex" CASCADE`,
674
669
  `DROP INDEX "from" CASCADE`,
675
670
  `CREATE INDEX "tableAddIndexIndex" ON "table" ("addIndex")`,
676
- `CREATE UNIQUE INDEX "tableAddIndexWithOptionsIndex" ON "table" USING using ("addIndexWithOptions"(expression) COLLATE 'collate' operator order) INCLUDE ("a", "b") WITH (with) TABLESPACE tablespace WHERE where`,
677
- `CREATE UNIQUE INDEX "to" ON "table" USING to ("changeIndex"(to) COLLATE 'to' to to) INCLUDE ("c", "d") WITH (to) TABLESPACE to WHERE to`,
671
+ `CREATE UNIQUE INDEX "tableAddIndexWithOptionsIndex" ON "table" USING using ("addIndexWithOptions" COLLATE 'collate' opclass order) INCLUDE ("a", "b") WITH (with) TABLESPACE tablespace WHERE where`,
672
+ `CREATE UNIQUE INDEX "to" ON "table" USING to ("changeIndex" COLLATE 'to' to to) INCLUDE ("c", "d") WITH (to) TABLESPACE to WHERE to`,
678
673
  ]);
679
674
 
680
675
  queryMock.mockClear();
@@ -685,8 +680,8 @@ describe('changeTable', () => {
685
680
  `DROP INDEX "tableAddIndexWithOptionsIndex" CASCADE`,
686
681
  `DROP INDEX "to" RESTRICT`,
687
682
  `CREATE INDEX "tableRemoveIndexIndex" ON "table" ("removeIndex")`,
688
- `CREATE UNIQUE INDEX "tableRemoveIndexWithOptionsIndex" ON "table" USING using ("removeIndexWithOptions"(expression) COLLATE 'collate' operator order) INCLUDE ("a", "b") WITH (with) TABLESPACE tablespace WHERE where`,
689
- `CREATE INDEX "from" ON "table" USING from ("changeIndex"(from) COLLATE 'from' from from) INCLUDE ("a", "b") WITH (from) TABLESPACE from WHERE from`,
683
+ `CREATE UNIQUE INDEX "tableRemoveIndexWithOptionsIndex" ON "table" USING using ("removeIndexWithOptions" COLLATE 'collate' opclass order) INCLUDE ("a", "b") WITH (with) TABLESPACE tablespace WHERE where`,
684
+ `CREATE INDEX "from" ON "table" USING from ("changeIndex" COLLATE 'from' from from) INCLUDE ("a", "b") WITH (from) TABLESPACE from WHERE from`,
690
685
  ]);
691
686
  });
692
687
 
@@ -127,8 +127,8 @@ const columnTypeToColumnChange = (
127
127
  item: ColumnType | Change,
128
128
  ): RakeDbAst.ColumnChange => {
129
129
  if (item instanceof ColumnType) {
130
- const foreignKey = item.data.foreignKey;
131
- if (foreignKey && 'fn' in foreignKey) {
130
+ const foreignKeys = item.data.foreignKeys;
131
+ if (foreignKeys?.some((it) => 'fn' in it)) {
132
132
  throw new Error('Callback in foreignKey is not allowed in migration');
133
133
  }
134
134
 
@@ -138,7 +138,7 @@ const columnTypeToColumnChange = (
138
138
  nullable: item.data.isNullable,
139
139
  primaryKey: item.isPrimaryKey,
140
140
  ...item.data,
141
- foreignKey,
141
+ foreignKeys: foreignKeys as RakeDbAst.ColumnChange['foreignKeys'],
142
142
  };
143
143
  }
144
144
 
@@ -395,83 +395,96 @@ const astToQueries = (ast: RakeDbAst.ChangeTable): Sql[] => {
395
395
  );
396
396
  }
397
397
 
398
- const fromFkey = from.foreignKey;
399
- const toFkey = to.foreignKey;
400
- if (
401
- (fromFkey || toFkey) &&
402
- (!fromFkey ||
403
- !toFkey ||
404
- fromFkey.name !== toFkey.name ||
405
- fromFkey.match !== toFkey.match ||
406
- fromFkey.onUpdate !== toFkey.onUpdate ||
407
- fromFkey.onDelete !== toFkey.onDelete ||
408
- fromFkey.dropMode !== toFkey.dropMode ||
409
- fromFkey.table !== toFkey.table ||
410
- fromFkey.columns.join(',') !== toFkey.columns.join(','))
411
- ) {
412
- if (fromFkey) {
413
- dropForeignKeys.push({
414
- columns: [key],
415
- fnOrTable: fromFkey.table,
416
- foreignColumns: fromFkey.columns,
417
- options: fromFkey,
418
- });
419
- }
420
-
421
- if (toFkey) {
422
- addForeignKeys.push({
423
- columns: [key],
424
- fnOrTable: toFkey.table,
425
- foreignColumns: toFkey.columns,
426
- options: toFkey,
427
- });
398
+ const foreignKeysLen = Math.max(
399
+ from.foreignKeys?.length || 0,
400
+ to.foreignKeys?.length || 0,
401
+ );
402
+ for (let i = 0; i < foreignKeysLen; i++) {
403
+ const fromFkey = from.foreignKeys?.[i];
404
+ const toFkey = to.foreignKeys?.[i];
405
+
406
+ if (
407
+ (fromFkey || toFkey) &&
408
+ (!fromFkey ||
409
+ !toFkey ||
410
+ fromFkey.name !== toFkey.name ||
411
+ fromFkey.match !== toFkey.match ||
412
+ fromFkey.onUpdate !== toFkey.onUpdate ||
413
+ fromFkey.onDelete !== toFkey.onDelete ||
414
+ fromFkey.dropMode !== toFkey.dropMode ||
415
+ fromFkey.table !== toFkey.table ||
416
+ fromFkey.columns.join(',') !== toFkey.columns.join(','))
417
+ ) {
418
+ if (fromFkey) {
419
+ dropForeignKeys.push({
420
+ columns: [key],
421
+ fnOrTable: fromFkey.table,
422
+ foreignColumns: fromFkey.columns,
423
+ options: fromFkey,
424
+ });
425
+ }
426
+
427
+ if (toFkey) {
428
+ addForeignKeys.push({
429
+ columns: [key],
430
+ fnOrTable: toFkey.table,
431
+ foreignColumns: toFkey.columns,
432
+ options: toFkey,
433
+ });
434
+ }
428
435
  }
429
436
  }
430
437
 
431
- const fromIndex = from.index;
432
- const toIndex = to.index;
433
- if (
434
- (fromIndex || toIndex) &&
435
- (!fromIndex ||
436
- !toIndex ||
437
- fromIndex.expression !== toIndex.expression ||
438
- fromIndex.collate !== toIndex.collate ||
439
- fromIndex.operator !== toIndex.operator ||
440
- fromIndex.order !== toIndex.order ||
441
- fromIndex.name !== toIndex.name ||
442
- fromIndex.unique !== toIndex.unique ||
443
- fromIndex.using !== toIndex.using ||
444
- fromIndex.include !== toIndex.include ||
445
- (Array.isArray(fromIndex.include) &&
446
- Array.isArray(toIndex.include) &&
447
- fromIndex.include.join(',') !== toIndex.include.join(',')) ||
448
- fromIndex.with !== toIndex.with ||
449
- fromIndex.tablespace !== toIndex.tablespace ||
450
- fromIndex.where !== toIndex.where ||
451
- fromIndex.dropMode !== toIndex.dropMode)
452
- ) {
453
- if (fromIndex) {
454
- dropIndexes.push({
455
- columns: [
456
- {
457
- column: key,
458
- ...fromIndex,
459
- },
460
- ],
461
- options: fromIndex,
462
- });
463
- }
464
-
465
- if (toIndex) {
466
- addIndexes.push({
467
- columns: [
468
- {
469
- column: key,
470
- ...toIndex,
471
- },
472
- ],
473
- options: toIndex,
474
- });
438
+ const indexesLen = Math.max(
439
+ from.indexes?.length || 0,
440
+ to.indexes?.length || 0,
441
+ );
442
+ for (let i = 0; i < indexesLen; i++) {
443
+ const fromIndex = from.indexes?.[i];
444
+ const toIndex = to.indexes?.[i];
445
+
446
+ if (
447
+ (fromIndex || toIndex) &&
448
+ (!fromIndex ||
449
+ !toIndex ||
450
+ fromIndex.collate !== toIndex.collate ||
451
+ fromIndex.opclass !== toIndex.opclass ||
452
+ fromIndex.order !== toIndex.order ||
453
+ fromIndex.name !== toIndex.name ||
454
+ fromIndex.unique !== toIndex.unique ||
455
+ fromIndex.using !== toIndex.using ||
456
+ fromIndex.include !== toIndex.include ||
457
+ (Array.isArray(fromIndex.include) &&
458
+ Array.isArray(toIndex.include) &&
459
+ fromIndex.include.join(',') !== toIndex.include.join(',')) ||
460
+ fromIndex.with !== toIndex.with ||
461
+ fromIndex.tablespace !== toIndex.tablespace ||
462
+ fromIndex.where !== toIndex.where ||
463
+ fromIndex.dropMode !== toIndex.dropMode)
464
+ ) {
465
+ if (fromIndex) {
466
+ dropIndexes.push({
467
+ columns: [
468
+ {
469
+ column: key,
470
+ ...fromIndex,
471
+ },
472
+ ],
473
+ options: fromIndex,
474
+ });
475
+ }
476
+
477
+ if (toIndex) {
478
+ addIndexes.push({
479
+ columns: [
480
+ {
481
+ column: key,
482
+ ...toIndex,
483
+ },
484
+ ],
485
+ options: toIndex,
486
+ });
487
+ }
475
488
  }
476
489
  }
477
490
 
@@ -63,9 +63,8 @@ const db = getDb();
63
63
  name: 'indexName',
64
64
  unique: true,
65
65
  using: 'gin',
66
- expression: 10,
67
66
  collate: 'utf-8',
68
- operator: 'operator',
67
+ opclass: 'opclass',
69
68
  order: 'ASC',
70
69
  include: 'id',
71
70
  with: 'fillfactor = 70',
@@ -113,7 +112,7 @@ const db = getDb();
113
112
  CREATE UNIQUE INDEX "indexName"
114
113
  ON "table"
115
114
  USING gin
116
- ("withIndex"(10) COLLATE 'utf-8' operator ASC)
115
+ ("withIndex" COLLATE 'utf-8' opclass ASC)
117
116
  INCLUDE ("id")
118
117
  WITH (fillfactor = 70)
119
118
  TABLESPACE tablespace
@@ -51,17 +51,19 @@ export const columnToSql = (
51
51
  }
52
52
  }
53
53
 
54
- const { foreignKey } = item.data;
55
- if (foreignKey) {
56
- const [schema, table] = getForeignKeyTable(
57
- 'fn' in foreignKey ? foreignKey.fn : foreignKey.table,
58
- );
54
+ const { foreignKeys } = item.data;
55
+ if (foreignKeys) {
56
+ for (const foreignKey of foreignKeys) {
57
+ const [schema, table] = getForeignKeyTable(
58
+ 'fn' in foreignKey ? foreignKey.fn : foreignKey.table,
59
+ );
59
60
 
60
- if (foreignKey.name) {
61
- line.push(`CONSTRAINT "${foreignKey.name}"`);
62
- }
61
+ if (foreignKey.name) {
62
+ line.push(`CONSTRAINT "${foreignKey.name}"`);
63
+ }
63
64
 
64
- line.push(referencesToSql(schema, table, foreignKey.columns, foreignKey));
65
+ line.push(referencesToSql(schema, table, foreignKey.columns, foreignKey));
66
+ }
65
67
  }
66
68
 
67
69
  return line.join(' ');
@@ -72,13 +74,13 @@ export const addColumnIndex = (
72
74
  key: string,
73
75
  item: ColumnType,
74
76
  ) => {
75
- if (item.data) {
76
- if (item.data.index) {
77
- indexes.push({
78
- columns: [{ ...item.data.index, column: key }],
79
- options: item.data.index,
80
- });
81
- }
77
+ if (item.data.indexes) {
78
+ indexes.push(
79
+ ...item.data.indexes.map((index) => ({
80
+ columns: [{ ...index, column: key }],
81
+ options: index,
82
+ })),
83
+ );
82
84
  }
83
85
  };
84
86
 
@@ -162,7 +164,13 @@ export const indexesToQuery = (
162
164
  return indexes.map(({ columns, options }) => {
163
165
  const indexName =
164
166
  options.name ||
165
- joinWords(name, ...columns.map(({ column }) => column), 'index');
167
+ joinWords(
168
+ name,
169
+ ...columns
170
+ .filter((it): it is { column: string } => 'column' in it)
171
+ .map((it) => it.column),
172
+ 'index',
173
+ );
166
174
 
167
175
  if (!up) {
168
176
  return {
@@ -191,17 +199,15 @@ export const indexesToQuery = (
191
199
 
192
200
  columns.forEach((column) => {
193
201
  const columnSql: string[] = [
194
- `"${column.column}"${
195
- column.expression ? `(${column.expression})` : ''
196
- }`,
202
+ 'column' in column ? `"${column.column}"` : `(${column.expression})`,
197
203
  ];
198
204
 
199
205
  if (column.collate) {
200
206
  columnSql.push(`COLLATE '${column.collate}'`);
201
207
  }
202
208
 
203
- if (column.operator) {
204
- columnSql.push(column.operator);
209
+ if (column.opclass) {
210
+ columnSql.push(column.opclass);
205
211
  }
206
212
 
207
213
  if (column.order) {
@@ -20,7 +20,7 @@ describe('dbStructure', () => {
20
20
 
21
21
  describe('getTables', () => {
22
22
  it('should return tables', async () => {
23
- rows = [{ schemaName: 'schema', name: 'table' }];
23
+ rows = [{ schemaName: 'schema', name: 'table', comment: 'comment' }];
24
24
  const result = await db.getTables();
25
25
  expect(result).toEqual(rows);
26
26
  });
@@ -65,6 +65,9 @@ describe('dbStructure', () => {
65
65
  type: 'int4',
66
66
  default: '123',
67
67
  isNullable: false,
68
+ collation: 'en_US',
69
+ compression: 'p',
70
+ comment: 'column comment',
68
71
  },
69
72
  ];
70
73
  const result = await db.getColumns();
@@ -78,10 +81,13 @@ describe('dbStructure', () => {
78
81
  {
79
82
  schemaName: 'public',
80
83
  tableName: 'table',
81
- columnNames: ['column'],
82
84
  name: 'indexName',
83
85
  isUnique: true,
84
- isPrimary: true,
86
+ columns: [{ column: 'column' }],
87
+ include: null,
88
+ with: null,
89
+ tablespace: null,
90
+ where: null,
85
91
  },
86
92
  ];
87
93
  const result = await db.getIndexes();
@@ -100,6 +106,9 @@ describe('dbStructure', () => {
100
106
  name: 'name',
101
107
  columnNames: ['column'],
102
108
  foreignColumnNames: ['foreignColumn'],
109
+ match: 's',
110
+ onUpdate: 'a',
111
+ onDelete: 'a',
103
112
  },
104
113
  ];
105
114
  const result = await db.getForeignKeys();
@@ -107,18 +116,17 @@ describe('dbStructure', () => {
107
116
  });
108
117
  });
109
118
 
110
- describe('getConstraints', () => {
119
+ describe('getPrimaryKeys', () => {
111
120
  it('should return constraints', async () => {
112
121
  rows = [
113
122
  {
114
123
  schemaName: 'public',
115
124
  tableName: 'table',
116
125
  name: 'name',
117
- type: 'PRIMARY KEY',
118
126
  columnNames: ['id'],
119
127
  },
120
128
  ];
121
- const result = await db.getConstraints();
129
+ const result = await db.getPrimaryKeys();
122
130
  expect(result).toEqual(rows);
123
131
  });
124
132
  });