rake-db 2.17.1 → 2.17.3
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/dist/index.d.ts +172 -5
- package/dist/index.js +294 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +292 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as orchid_core from 'orchid-core';
|
|
2
|
-
import { EmptyObject, RawSQLBase, ColumnSchemaConfig, MaybeArray, ColumnTypeBase, RecordOptionalString } from 'orchid-core';
|
|
2
|
+
import { EmptyObject, RawSQLBase, ColumnSchemaConfig, MaybeArray, RecordString, ColumnTypeBase, RecordOptionalString } from 'orchid-core';
|
|
3
3
|
import * as pqb from 'pqb';
|
|
4
4
|
import { ColumnsShape, Db as Db$1, ColumnType, EnumColumn, raw, Adapter, IndexColumnOptions, IndexOptions, ForeignKeyOptions, DbResult, TransactionAdapter, QueryLogObject, TextColumn, TableData, NoPrimaryKeyOption, SingleColumnIndexOptions, DefaultColumnTypes, DefaultSchemaConfig, QueryLogOptions, AdapterOptions } from 'pqb';
|
|
5
5
|
|
|
@@ -584,6 +584,141 @@ declare class Migration<CT extends RakeDbColumnTypes> {
|
|
|
584
584
|
* @param options - enum options
|
|
585
585
|
*/
|
|
586
586
|
dropEnum(name: string, values: [string, ...string[]], options?: Omit<RakeDbAst.Enum, 'type' | 'action' | 'name' | 'values' | 'schema'>): Promise<void>;
|
|
587
|
+
/**
|
|
588
|
+
* Use these methods to add or drop one or multiple values from an existing enum.
|
|
589
|
+
*
|
|
590
|
+
* `addEnumValues` will drop values when rolling back the migration.
|
|
591
|
+
*
|
|
592
|
+
* Dropping a value internally acts in multiple steps:
|
|
593
|
+
*
|
|
594
|
+
* 1. Select all columns from the database that depends on the enum;
|
|
595
|
+
* 2. Alter all these columns to have text type;
|
|
596
|
+
* 3. Drop the enum;
|
|
597
|
+
* 4. Re-create the enum without the value given;
|
|
598
|
+
* 5. Alter all columns from the first step to have the enum type;
|
|
599
|
+
*
|
|
600
|
+
* In the case when the value is used by some table,
|
|
601
|
+
* migrating `dropEnumValue` or rolling back `addEnumValue` will throw an error with a descriptive message,
|
|
602
|
+
* in such case you'd need to manually resolve the issue by deleting rows with the value, or changing such values.
|
|
603
|
+
*
|
|
604
|
+
* ```ts
|
|
605
|
+
* import { change } from '../dbScript';
|
|
606
|
+
*
|
|
607
|
+
* change(async (db) => {
|
|
608
|
+
* await db.addEnumValue('numbers', 'four');
|
|
609
|
+
*
|
|
610
|
+
* // you can pass options
|
|
611
|
+
* await db.addEnumValue('numbers', 'three', {
|
|
612
|
+
* // where to insert
|
|
613
|
+
* before: 'four',
|
|
614
|
+
* // skip if already exists
|
|
615
|
+
* ifNotExists: true,
|
|
616
|
+
* });
|
|
617
|
+
*
|
|
618
|
+
* // enum name can be prefixed with schema
|
|
619
|
+
* await db.addEnumValue('public.numbers', 'five', {
|
|
620
|
+
* after: 'four',
|
|
621
|
+
* });
|
|
622
|
+
* });
|
|
623
|
+
* ```
|
|
624
|
+
*
|
|
625
|
+
* @param enumName - target enum name
|
|
626
|
+
* @param values - array of values to add
|
|
627
|
+
* @param options - optional object with options
|
|
628
|
+
* @param options.before - insert before the specified value
|
|
629
|
+
* @param options.after - insert after the specified value
|
|
630
|
+
* @param options.ifNotExists - skip adding if already exists
|
|
631
|
+
*/
|
|
632
|
+
addEnumValues(enumName: string, values: string[], options?: AddEnumValueOptions): Promise<void>;
|
|
633
|
+
/**
|
|
634
|
+
* See {@link addEnumValues}
|
|
635
|
+
*/
|
|
636
|
+
dropEnumValues(enumName: string, values: string[], options?: AddEnumValueOptions): Promise<void>;
|
|
637
|
+
/**
|
|
638
|
+
* Rename one or multiple enum values using this method:
|
|
639
|
+
*
|
|
640
|
+
* ```ts
|
|
641
|
+
* import { change } from '../dbScript';
|
|
642
|
+
*
|
|
643
|
+
* change(async (db) => {
|
|
644
|
+
* // rename value "from" to "to"
|
|
645
|
+
* await db.rename('numbers', { from: 'to' });
|
|
646
|
+
*
|
|
647
|
+
* // enum name can be prefixed with schema
|
|
648
|
+
* await db.rename('public.numbers', { from: 'to' });
|
|
649
|
+
* });
|
|
650
|
+
* ```
|
|
651
|
+
*
|
|
652
|
+
* @param enumName - target enum name, can be prefixed with schema
|
|
653
|
+
* @param values - object where keys are for old names, values are for new names
|
|
654
|
+
*/
|
|
655
|
+
renameEnumValues(enumName: string, values: RecordString): Promise<void>;
|
|
656
|
+
/**
|
|
657
|
+
* Drops the enum and re-creates it with a new set of values.
|
|
658
|
+
* Before dropping, changes all related column types to text, and after creating changes types back to the enum,
|
|
659
|
+
* in the same way as [dropEnumValues](/guide/migration-writing.html#addenumvalues,-dropenumvalues) works.
|
|
660
|
+
*
|
|
661
|
+
* ```ts
|
|
662
|
+
* import { change } from '../dbScript';
|
|
663
|
+
*
|
|
664
|
+
* change(async (db) => {
|
|
665
|
+
* await db.changeEnumValues(
|
|
666
|
+
* // can be prefixed with schema: 'public.numbers'
|
|
667
|
+
* 'numbers',
|
|
668
|
+
* // change from:
|
|
669
|
+
* ['one', 'two'],
|
|
670
|
+
* // change to:
|
|
671
|
+
* ['three', 'four'],
|
|
672
|
+
* );
|
|
673
|
+
* });
|
|
674
|
+
* ```
|
|
675
|
+
*
|
|
676
|
+
* @param enumName - target enum name, can be prefixed with schema
|
|
677
|
+
* @param fromValues - array of values before the change
|
|
678
|
+
* @param toValues - array of values to set
|
|
679
|
+
*/
|
|
680
|
+
changeEnumValues(enumName: string, fromValues: string[], toValues: string[]): Promise<void>;
|
|
681
|
+
/**
|
|
682
|
+
* Rename a type (such as enum):
|
|
683
|
+
*
|
|
684
|
+
* ```ts
|
|
685
|
+
* import { change } from '../dbScript';
|
|
686
|
+
*
|
|
687
|
+
* change(async (db) => {
|
|
688
|
+
* await db.renameType('oldTypeName', 'newTypeName');
|
|
689
|
+
* });
|
|
690
|
+
* ```
|
|
691
|
+
*
|
|
692
|
+
* Prefix the type name with a schema to set a different schema:
|
|
693
|
+
*
|
|
694
|
+
* ```ts
|
|
695
|
+
* import { change } from '../dbScript';
|
|
696
|
+
*
|
|
697
|
+
* change(async (db) => {
|
|
698
|
+
* await db.renameType('fromSchema.oldType', 'toSchema.newType');
|
|
699
|
+
* });
|
|
700
|
+
* ```
|
|
701
|
+
*
|
|
702
|
+
* @param from - rename the type from
|
|
703
|
+
* @param to - rename the type to
|
|
704
|
+
*/
|
|
705
|
+
renameType(from: string, to: string): Promise<void>;
|
|
706
|
+
/**
|
|
707
|
+
* Set a different schema to the type (such as enum):
|
|
708
|
+
*
|
|
709
|
+
* ```ts
|
|
710
|
+
* import { change } from '../dbScript';
|
|
711
|
+
*
|
|
712
|
+
* change(async (db) => {
|
|
713
|
+
* await db.changeTypeSchema('typeName', 'fromSchema', 'toSchema');
|
|
714
|
+
* });
|
|
715
|
+
* ```
|
|
716
|
+
*
|
|
717
|
+
* @param name - type name
|
|
718
|
+
* @param from - current table schema
|
|
719
|
+
* @param to - desired table schema
|
|
720
|
+
*/
|
|
721
|
+
changeTypeSchema(name: string, from: string, to: string): Promise<void>;
|
|
587
722
|
/**
|
|
588
723
|
* Domain is a custom database type that allows to predefine a `NOT NULL` and a `CHECK` (see [postgres tutorial](https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-user-defined-data-types/)).
|
|
589
724
|
*
|
|
@@ -833,8 +968,16 @@ declare class Migration<CT extends RakeDbColumnTypes> {
|
|
|
833
968
|
*/
|
|
834
969
|
constraintExists(constraintName: string): Promise<boolean>;
|
|
835
970
|
}
|
|
971
|
+
declare const renameType: (migration: Migration<RakeDbColumnTypes>, from: string, to: string, table: boolean) => Promise<void>;
|
|
972
|
+
interface AddEnumValueOptions {
|
|
973
|
+
ifNotExists?: boolean;
|
|
974
|
+
before?: string;
|
|
975
|
+
after?: string;
|
|
976
|
+
}
|
|
977
|
+
declare const addOrDropEnumValues: (migration: Migration<RakeDbColumnTypes>, up: boolean, enumName: string, values: string[], options?: AddEnumValueOptions) => Promise<void>;
|
|
978
|
+
declare const changeEnumValues: (migration: Migration<RakeDbColumnTypes>, enumName: string, fromValues: string[], toValues: string[]) => Promise<void>;
|
|
836
979
|
|
|
837
|
-
type RakeDbAst = RakeDbAst.Table | RakeDbAst.ChangeTable | RakeDbAst.
|
|
980
|
+
type RakeDbAst = RakeDbAst.Table | RakeDbAst.ChangeTable | RakeDbAst.RenameType | RakeDbAst.Schema | RakeDbAst.Extension | RakeDbAst.Enum | RakeDbAst.EnumValues | RakeDbAst.RenameEnumValues | RakeDbAst.ChangeEnumValues | RakeDbAst.Domain | RakeDbAst.Collation | RakeDbAst.Constraint | RakeDbAst.View;
|
|
838
981
|
declare namespace RakeDbAst {
|
|
839
982
|
interface Table extends TableData {
|
|
840
983
|
type: 'table';
|
|
@@ -893,8 +1036,9 @@ declare namespace RakeDbAst {
|
|
|
893
1036
|
indexes?: Omit<SingleColumnIndexOptions, 'column' | 'expression'>[];
|
|
894
1037
|
identity?: TableData.Identity;
|
|
895
1038
|
}
|
|
896
|
-
interface
|
|
897
|
-
type: '
|
|
1039
|
+
interface RenameType {
|
|
1040
|
+
type: 'renameType';
|
|
1041
|
+
table: boolean;
|
|
898
1042
|
fromSchema?: string;
|
|
899
1043
|
from: string;
|
|
900
1044
|
toSchema?: string;
|
|
@@ -924,6 +1068,29 @@ declare namespace RakeDbAst {
|
|
|
924
1068
|
cascade?: boolean;
|
|
925
1069
|
dropIfExists?: boolean;
|
|
926
1070
|
}
|
|
1071
|
+
interface EnumValues {
|
|
1072
|
+
type: 'enumValues';
|
|
1073
|
+
action: 'add' | 'drop';
|
|
1074
|
+
schema?: string;
|
|
1075
|
+
name: string;
|
|
1076
|
+
values: string[];
|
|
1077
|
+
place?: 'before' | 'after';
|
|
1078
|
+
relativeTo?: string;
|
|
1079
|
+
ifNotExists?: boolean;
|
|
1080
|
+
}
|
|
1081
|
+
interface RenameEnumValues {
|
|
1082
|
+
type: 'renameEnumValues';
|
|
1083
|
+
schema?: string;
|
|
1084
|
+
name: string;
|
|
1085
|
+
values: RecordString;
|
|
1086
|
+
}
|
|
1087
|
+
interface ChangeEnumValues {
|
|
1088
|
+
type: 'changeEnumValues';
|
|
1089
|
+
schema?: string;
|
|
1090
|
+
name: string;
|
|
1091
|
+
fromValues: string[];
|
|
1092
|
+
toValues: string[];
|
|
1093
|
+
}
|
|
927
1094
|
interface Domain {
|
|
928
1095
|
type: 'domain';
|
|
929
1096
|
action: 'create' | 'drop';
|
|
@@ -1268,4 +1435,4 @@ type RakeDbChangeFn<CT extends RakeDbColumnTypes> = (fn: ChangeCallback<CT>) =>
|
|
|
1268
1435
|
declare const rakeDb: RakeDbFn;
|
|
1269
1436
|
declare const rakeDbAliases: RecordOptionalString;
|
|
1270
1437
|
|
|
1271
|
-
export { AnyRakeDbConfig, AppCodeUpdater, AppCodeUpdaterParams, ChangeTableCallback, ChangeTableOptions, ColumnComment, ColumnsShapeCallback, ConstraintArg, DbMigration, DropMode, InputRakeDbConfig, Migration, MigrationAdapter, MigrationColumnTypes, ModuleExportsRecord, NoMigrationsTableError, RAKE_DB_LOCK_KEY, RakeDbAppliedVersions, RakeDbAst, RakeDbBaseTable, RakeDbChangeFn, RakeDbColumnTypes, RakeDbConfig, RakeDbFn, RakeDbFnReturns, RakeDbLazyFn, RakeDbMigrationId, RakeDbResult, SilentQueries, TableOptions, changeCache, createDb, createMigrationInterface, deleteMigratedVersion, dropDb, generate, generateTimeStamp, getDatabaseAndUserFromOptions, getMigratedVersionsMap, makeFileVersion, migrate, migrateOrRollback, migrationConfigDefaults, processRakeDbConfig, rakeDb, rakeDbAliases, redo, resetDb, rollback, saveMigratedVersion, writeMigrationFile };
|
|
1438
|
+
export { AnyRakeDbConfig, AppCodeUpdater, AppCodeUpdaterParams, ChangeTableCallback, ChangeTableOptions, ColumnComment, ColumnsShapeCallback, ConstraintArg, DbMigration, DropMode, InputRakeDbConfig, Migration, MigrationAdapter, MigrationColumnTypes, ModuleExportsRecord, NoMigrationsTableError, RAKE_DB_LOCK_KEY, RakeDbAppliedVersions, RakeDbAst, RakeDbBaseTable, RakeDbChangeFn, RakeDbColumnTypes, RakeDbConfig, RakeDbFn, RakeDbFnReturns, RakeDbLazyFn, RakeDbMigrationId, RakeDbResult, SilentQueries, TableOptions, addOrDropEnumValues, changeCache, changeEnumValues, createDb, createMigrationInterface, deleteMigratedVersion, dropDb, generate, generateTimeStamp, getDatabaseAndUserFromOptions, getMigratedVersionsMap, makeFileVersion, migrate, migrateOrRollback, migrationConfigDefaults, processRakeDbConfig, rakeDb, rakeDbAliases, redo, renameType, resetDb, rollback, saveMigratedVersion, writeMigrationFile };
|
package/dist/index.js
CHANGED
|
@@ -1218,28 +1218,8 @@ class Migration {
|
|
|
1218
1218
|
* @param from - rename the table from
|
|
1219
1219
|
* @param to - rename the table to
|
|
1220
1220
|
*/
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
const [fromSchema, f] = getSchemaAndTableFromName(this.up ? from : to);
|
|
1224
|
-
const [toSchema, t] = getSchemaAndTableFromName(this.up ? to : from);
|
|
1225
|
-
const ast = {
|
|
1226
|
-
type: "renameTable",
|
|
1227
|
-
fromSchema,
|
|
1228
|
-
from: f,
|
|
1229
|
-
toSchema,
|
|
1230
|
-
to: t
|
|
1231
|
-
};
|
|
1232
|
-
if (ast.from !== ast.to) {
|
|
1233
|
-
await this.adapter.query(
|
|
1234
|
-
`ALTER TABLE ${quoteTable(ast.fromSchema, ast.from)} RENAME TO "${ast.to}"`
|
|
1235
|
-
);
|
|
1236
|
-
}
|
|
1237
|
-
if (ast.fromSchema !== ast.toSchema) {
|
|
1238
|
-
await this.adapter.query(
|
|
1239
|
-
`ALTER TABLE ${quoteTable(ast.fromSchema, ast.to)} SET SCHEMA "${(_a = ast.toSchema) != null ? _a : this.adapter.schema}"`
|
|
1240
|
-
);
|
|
1241
|
-
}
|
|
1242
|
-
this.migratedAsts.push(ast);
|
|
1221
|
+
renameTable(from, to) {
|
|
1222
|
+
return renameType(this, from, to, true);
|
|
1243
1223
|
}
|
|
1244
1224
|
/**
|
|
1245
1225
|
* Set a different schema to the table:
|
|
@@ -1609,6 +1589,168 @@ class Migration {
|
|
|
1609
1589
|
dropEnum(name, values, options) {
|
|
1610
1590
|
return createEnum$1(this, !this.up, name, values, options);
|
|
1611
1591
|
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Use these methods to add or drop one or multiple values from an existing enum.
|
|
1594
|
+
*
|
|
1595
|
+
* `addEnumValues` will drop values when rolling back the migration.
|
|
1596
|
+
*
|
|
1597
|
+
* Dropping a value internally acts in multiple steps:
|
|
1598
|
+
*
|
|
1599
|
+
* 1. Select all columns from the database that depends on the enum;
|
|
1600
|
+
* 2. Alter all these columns to have text type;
|
|
1601
|
+
* 3. Drop the enum;
|
|
1602
|
+
* 4. Re-create the enum without the value given;
|
|
1603
|
+
* 5. Alter all columns from the first step to have the enum type;
|
|
1604
|
+
*
|
|
1605
|
+
* In the case when the value is used by some table,
|
|
1606
|
+
* migrating `dropEnumValue` or rolling back `addEnumValue` will throw an error with a descriptive message,
|
|
1607
|
+
* in such case you'd need to manually resolve the issue by deleting rows with the value, or changing such values.
|
|
1608
|
+
*
|
|
1609
|
+
* ```ts
|
|
1610
|
+
* import { change } from '../dbScript';
|
|
1611
|
+
*
|
|
1612
|
+
* change(async (db) => {
|
|
1613
|
+
* await db.addEnumValue('numbers', 'four');
|
|
1614
|
+
*
|
|
1615
|
+
* // you can pass options
|
|
1616
|
+
* await db.addEnumValue('numbers', 'three', {
|
|
1617
|
+
* // where to insert
|
|
1618
|
+
* before: 'four',
|
|
1619
|
+
* // skip if already exists
|
|
1620
|
+
* ifNotExists: true,
|
|
1621
|
+
* });
|
|
1622
|
+
*
|
|
1623
|
+
* // enum name can be prefixed with schema
|
|
1624
|
+
* await db.addEnumValue('public.numbers', 'five', {
|
|
1625
|
+
* after: 'four',
|
|
1626
|
+
* });
|
|
1627
|
+
* });
|
|
1628
|
+
* ```
|
|
1629
|
+
*
|
|
1630
|
+
* @param enumName - target enum name
|
|
1631
|
+
* @param values - array of values to add
|
|
1632
|
+
* @param options - optional object with options
|
|
1633
|
+
* @param options.before - insert before the specified value
|
|
1634
|
+
* @param options.after - insert after the specified value
|
|
1635
|
+
* @param options.ifNotExists - skip adding if already exists
|
|
1636
|
+
*/
|
|
1637
|
+
addEnumValues(enumName, values, options) {
|
|
1638
|
+
return addOrDropEnumValues(this, this.up, enumName, values, options);
|
|
1639
|
+
}
|
|
1640
|
+
/**
|
|
1641
|
+
* See {@link addEnumValues}
|
|
1642
|
+
*/
|
|
1643
|
+
dropEnumValues(enumName, values, options) {
|
|
1644
|
+
return addOrDropEnumValues(this, !this.up, enumName, values, options);
|
|
1645
|
+
}
|
|
1646
|
+
/**
|
|
1647
|
+
* Rename one or multiple enum values using this method:
|
|
1648
|
+
*
|
|
1649
|
+
* ```ts
|
|
1650
|
+
* import { change } from '../dbScript';
|
|
1651
|
+
*
|
|
1652
|
+
* change(async (db) => {
|
|
1653
|
+
* // rename value "from" to "to"
|
|
1654
|
+
* await db.rename('numbers', { from: 'to' });
|
|
1655
|
+
*
|
|
1656
|
+
* // enum name can be prefixed with schema
|
|
1657
|
+
* await db.rename('public.numbers', { from: 'to' });
|
|
1658
|
+
* });
|
|
1659
|
+
* ```
|
|
1660
|
+
*
|
|
1661
|
+
* @param enumName - target enum name, can be prefixed with schema
|
|
1662
|
+
* @param values - object where keys are for old names, values are for new names
|
|
1663
|
+
*/
|
|
1664
|
+
async renameEnumValues(enumName, values) {
|
|
1665
|
+
const [schema, name] = getSchemaAndTableFromName(enumName);
|
|
1666
|
+
const ast = {
|
|
1667
|
+
type: "renameEnumValues",
|
|
1668
|
+
schema,
|
|
1669
|
+
name,
|
|
1670
|
+
values
|
|
1671
|
+
};
|
|
1672
|
+
for (const pair of Object.entries(ast.values)) {
|
|
1673
|
+
const [from, to] = this.up ? pair : [pair[1], pair[0]];
|
|
1674
|
+
await this.adapter.query(
|
|
1675
|
+
`ALTER TYPE ${quoteTable(
|
|
1676
|
+
ast.schema,
|
|
1677
|
+
ast.name
|
|
1678
|
+
)} RENAME VALUE "${from}" TO "${to}"`
|
|
1679
|
+
);
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
/**
|
|
1683
|
+
* Drops the enum and re-creates it with a new set of values.
|
|
1684
|
+
* Before dropping, changes all related column types to text, and after creating changes types back to the enum,
|
|
1685
|
+
* in the same way as [dropEnumValues](/guide/migration-writing.html#addenumvalues,-dropenumvalues) works.
|
|
1686
|
+
*
|
|
1687
|
+
* ```ts
|
|
1688
|
+
* import { change } from '../dbScript';
|
|
1689
|
+
*
|
|
1690
|
+
* change(async (db) => {
|
|
1691
|
+
* await db.changeEnumValues(
|
|
1692
|
+
* // can be prefixed with schema: 'public.numbers'
|
|
1693
|
+
* 'numbers',
|
|
1694
|
+
* // change from:
|
|
1695
|
+
* ['one', 'two'],
|
|
1696
|
+
* // change to:
|
|
1697
|
+
* ['three', 'four'],
|
|
1698
|
+
* );
|
|
1699
|
+
* });
|
|
1700
|
+
* ```
|
|
1701
|
+
*
|
|
1702
|
+
* @param enumName - target enum name, can be prefixed with schema
|
|
1703
|
+
* @param fromValues - array of values before the change
|
|
1704
|
+
* @param toValues - array of values to set
|
|
1705
|
+
*/
|
|
1706
|
+
changeEnumValues(enumName, fromValues, toValues) {
|
|
1707
|
+
return changeEnumValues(this, enumName, fromValues, toValues);
|
|
1708
|
+
}
|
|
1709
|
+
/**
|
|
1710
|
+
* Rename a type (such as enum):
|
|
1711
|
+
*
|
|
1712
|
+
* ```ts
|
|
1713
|
+
* import { change } from '../dbScript';
|
|
1714
|
+
*
|
|
1715
|
+
* change(async (db) => {
|
|
1716
|
+
* await db.renameType('oldTypeName', 'newTypeName');
|
|
1717
|
+
* });
|
|
1718
|
+
* ```
|
|
1719
|
+
*
|
|
1720
|
+
* Prefix the type name with a schema to set a different schema:
|
|
1721
|
+
*
|
|
1722
|
+
* ```ts
|
|
1723
|
+
* import { change } from '../dbScript';
|
|
1724
|
+
*
|
|
1725
|
+
* change(async (db) => {
|
|
1726
|
+
* await db.renameType('fromSchema.oldType', 'toSchema.newType');
|
|
1727
|
+
* });
|
|
1728
|
+
* ```
|
|
1729
|
+
*
|
|
1730
|
+
* @param from - rename the type from
|
|
1731
|
+
* @param to - rename the type to
|
|
1732
|
+
*/
|
|
1733
|
+
renameType(from, to) {
|
|
1734
|
+
return renameType(this, from, to, false);
|
|
1735
|
+
}
|
|
1736
|
+
/**
|
|
1737
|
+
* Set a different schema to the type (such as enum):
|
|
1738
|
+
*
|
|
1739
|
+
* ```ts
|
|
1740
|
+
* import { change } from '../dbScript';
|
|
1741
|
+
*
|
|
1742
|
+
* change(async (db) => {
|
|
1743
|
+
* await db.changeTypeSchema('typeName', 'fromSchema', 'toSchema');
|
|
1744
|
+
* });
|
|
1745
|
+
* ```
|
|
1746
|
+
*
|
|
1747
|
+
* @param name - type name
|
|
1748
|
+
* @param from - current table schema
|
|
1749
|
+
* @param to - desired table schema
|
|
1750
|
+
*/
|
|
1751
|
+
changeTypeSchema(name, from, to) {
|
|
1752
|
+
return this.renameType(`${from}.${name}`, `${to}.${name}`);
|
|
1753
|
+
}
|
|
1612
1754
|
/**
|
|
1613
1755
|
* Domain is a custom database type that allows to predefine a `NOT NULL` and a `CHECK` (see [postgres tutorial](https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-user-defined-data-types/)).
|
|
1614
1756
|
*
|
|
@@ -1968,6 +2110,133 @@ const createCollation$1 = async (migration, up, name, options) => {
|
|
|
1968
2110
|
const queryExists = (db, sql) => {
|
|
1969
2111
|
return db.adapter.query(sql).then(({ rowCount }) => rowCount > 0);
|
|
1970
2112
|
};
|
|
2113
|
+
const renameType = async (migration, from, to, table) => {
|
|
2114
|
+
var _a;
|
|
2115
|
+
const [fromSchema, f] = getSchemaAndTableFromName(migration.up ? from : to);
|
|
2116
|
+
const [toSchema, t] = getSchemaAndTableFromName(migration.up ? to : from);
|
|
2117
|
+
const ast = {
|
|
2118
|
+
type: "renameType",
|
|
2119
|
+
table,
|
|
2120
|
+
fromSchema,
|
|
2121
|
+
from: f,
|
|
2122
|
+
toSchema,
|
|
2123
|
+
to: t
|
|
2124
|
+
};
|
|
2125
|
+
const sqlKind = ast.table ? "TABLE" : "TYPE";
|
|
2126
|
+
if (ast.from !== ast.to) {
|
|
2127
|
+
await migration.adapter.query(
|
|
2128
|
+
`ALTER ${sqlKind} ${quoteTable(ast.fromSchema, ast.from)} RENAME TO "${ast.to}"`
|
|
2129
|
+
);
|
|
2130
|
+
}
|
|
2131
|
+
if (ast.fromSchema !== ast.toSchema) {
|
|
2132
|
+
await migration.adapter.query(
|
|
2133
|
+
`ALTER ${sqlKind} ${quoteTable(ast.fromSchema, ast.to)} SET SCHEMA "${(_a = ast.toSchema) != null ? _a : migration.adapter.schema}"`
|
|
2134
|
+
);
|
|
2135
|
+
}
|
|
2136
|
+
migration.migratedAsts.push(ast);
|
|
2137
|
+
};
|
|
2138
|
+
const addOrDropEnumValues = async (migration, up, enumName, values, options) => {
|
|
2139
|
+
var _a;
|
|
2140
|
+
const [schema, name] = getSchemaAndTableFromName(enumName);
|
|
2141
|
+
const quotedName = quoteTable(schema, name);
|
|
2142
|
+
const ast = {
|
|
2143
|
+
type: "enumValues",
|
|
2144
|
+
action: up ? "add" : "drop",
|
|
2145
|
+
schema,
|
|
2146
|
+
name,
|
|
2147
|
+
values,
|
|
2148
|
+
place: (options == null ? void 0 : options.before) ? "before" : (options == null ? void 0 : options.after) ? "after" : void 0,
|
|
2149
|
+
relativeTo: (_a = options == null ? void 0 : options.before) != null ? _a : options == null ? void 0 : options.after,
|
|
2150
|
+
ifNotExists: options == null ? void 0 : options.ifNotExists
|
|
2151
|
+
};
|
|
2152
|
+
if (ast.action === "add") {
|
|
2153
|
+
await Promise.all(
|
|
2154
|
+
(ast.place === "after" ? [...ast.values].reverse() : ast.values).map(
|
|
2155
|
+
(value) => migration.adapter.query(
|
|
2156
|
+
`ALTER TYPE ${quoteTable(ast.schema, ast.name)} ADD VALUE${ast.ifNotExists ? " IF NOT EXISTS" : ""} ${orchidCore.singleQuote(value)}${ast.place && ast.relativeTo ? ` ${ast.place.toUpperCase()} ${orchidCore.singleQuote(ast.relativeTo)}` : ""}`
|
|
2157
|
+
)
|
|
2158
|
+
)
|
|
2159
|
+
);
|
|
2160
|
+
return;
|
|
2161
|
+
}
|
|
2162
|
+
const { rows: valuesRows } = await migration.adapter.query(
|
|
2163
|
+
`SELECT unnest(enum_range(NULL::${quotedName}))::text value`
|
|
2164
|
+
);
|
|
2165
|
+
const existingValues = valuesRows.map((r) => r.value);
|
|
2166
|
+
await recreateEnum(
|
|
2167
|
+
migration,
|
|
2168
|
+
ast,
|
|
2169
|
+
existingValues.filter((v) => !ast.values.includes(v)),
|
|
2170
|
+
(quotedName2, table, column) => `Cannot drop ${quotedName2} enum values [${ast.values.map(orchidCore.singleQuote).join(
|
|
2171
|
+
", "
|
|
2172
|
+
)}]: table ${table} has a row with such value in the column "${column}"`
|
|
2173
|
+
);
|
|
2174
|
+
};
|
|
2175
|
+
const changeEnumValues = async (migration, enumName, fromValues, toValues) => {
|
|
2176
|
+
const [schema, name] = getSchemaAndTableFromName(enumName);
|
|
2177
|
+
if (!migration.up) {
|
|
2178
|
+
const values = fromValues;
|
|
2179
|
+
fromValues = toValues;
|
|
2180
|
+
toValues = values;
|
|
2181
|
+
}
|
|
2182
|
+
const ast = {
|
|
2183
|
+
type: "changeEnumValues",
|
|
2184
|
+
schema,
|
|
2185
|
+
name,
|
|
2186
|
+
fromValues,
|
|
2187
|
+
toValues
|
|
2188
|
+
};
|
|
2189
|
+
await recreateEnum(
|
|
2190
|
+
migration,
|
|
2191
|
+
ast,
|
|
2192
|
+
ast.toValues,
|
|
2193
|
+
(quotedName, table, column) => `Cannot change ${quotedName} enum values from [${fromValues.map(orchidCore.singleQuote).join(", ")}] to [${toValues.map(orchidCore.singleQuote).join(
|
|
2194
|
+
", "
|
|
2195
|
+
)}]: table ${table} has a row with removed value in the column "${column}"`
|
|
2196
|
+
);
|
|
2197
|
+
};
|
|
2198
|
+
const recreateEnum = async (migration, { schema, name }, values, errorMessage) => {
|
|
2199
|
+
const defaultSchema = migration.adapter.schema;
|
|
2200
|
+
const quotedName = quoteTable(schema, name);
|
|
2201
|
+
const { rows: tables } = await migration.adapter.query(
|
|
2202
|
+
`SELECT n.nspname AS "schema",
|
|
2203
|
+
c.relname AS "table",
|
|
2204
|
+
json_agg(a.attname ORDER BY a.attnum) AS "columns"
|
|
2205
|
+
FROM pg_class c
|
|
2206
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = relnamespace
|
|
2207
|
+
JOIN pg_attribute a ON a.attrelid = c.oid
|
|
2208
|
+
JOIN pg_type t ON a.atttypid = t.oid AND t.typname = ${orchidCore.singleQuote(name)}
|
|
2209
|
+
JOIN pg_namespace tn ON tn.oid = t.typnamespace AND tn.nspname = ${orchidCore.singleQuote(
|
|
2210
|
+
schema != null ? schema : defaultSchema
|
|
2211
|
+
)}
|
|
2212
|
+
GROUP BY n.nspname, c.relname`
|
|
2213
|
+
);
|
|
2214
|
+
const sql = tables.map(
|
|
2215
|
+
(t) => `ALTER TABLE ${quoteTable(t.schema, t.table)}
|
|
2216
|
+
${t.columns.map((c) => ` ALTER COLUMN "${c}" TYPE text`).join(",\n")}`
|
|
2217
|
+
);
|
|
2218
|
+
sql.push(
|
|
2219
|
+
`DROP TYPE ${quotedName}`,
|
|
2220
|
+
`CREATE TYPE ${quotedName} AS ENUM (${values.map(orchidCore.singleQuote).join(", ")})`
|
|
2221
|
+
);
|
|
2222
|
+
await migration.adapter.query(sql.join(";\n"));
|
|
2223
|
+
for (const t of tables) {
|
|
2224
|
+
const table = quoteTable(t.schema, t.table);
|
|
2225
|
+
for (const c of t.columns) {
|
|
2226
|
+
try {
|
|
2227
|
+
await migration.adapter.query(
|
|
2228
|
+
`ALTER TABLE ${table}
|
|
2229
|
+
ALTER COLUMN "${c}" TYPE ${quotedName} USING "${c}"::${quotedName}`
|
|
2230
|
+
);
|
|
2231
|
+
} catch (err) {
|
|
2232
|
+
if (err.code === "22P02") {
|
|
2233
|
+
throw new Error(errorMessage(quotedName, table, c), { cause: err });
|
|
2234
|
+
}
|
|
2235
|
+
throw err;
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
};
|
|
1971
2240
|
|
|
1972
2241
|
const writeMigrationFile = async (config, version, name, content) => {
|
|
1973
2242
|
var _a;
|
|
@@ -4598,7 +4867,9 @@ Migrate and rollback common arguments:
|
|
|
4598
4867
|
exports.Migration = Migration;
|
|
4599
4868
|
exports.NoMigrationsTableError = NoMigrationsTableError;
|
|
4600
4869
|
exports.RAKE_DB_LOCK_KEY = RAKE_DB_LOCK_KEY;
|
|
4870
|
+
exports.addOrDropEnumValues = addOrDropEnumValues;
|
|
4601
4871
|
exports.changeCache = changeCache;
|
|
4872
|
+
exports.changeEnumValues = changeEnumValues;
|
|
4602
4873
|
exports.createDb = createDb;
|
|
4603
4874
|
exports.createMigrationInterface = createMigrationInterface;
|
|
4604
4875
|
exports.deleteMigratedVersion = deleteMigratedVersion;
|
|
@@ -4615,6 +4886,7 @@ exports.processRakeDbConfig = processRakeDbConfig;
|
|
|
4615
4886
|
exports.rakeDb = rakeDb;
|
|
4616
4887
|
exports.rakeDbAliases = rakeDbAliases;
|
|
4617
4888
|
exports.redo = redo;
|
|
4889
|
+
exports.renameType = renameType;
|
|
4618
4890
|
exports.resetDb = resetDb;
|
|
4619
4891
|
exports.rollback = rollback;
|
|
4620
4892
|
exports.saveMigratedVersion = saveMigratedVersion;
|