diff --git a/packages/data-store/src/entities/PreMigrationEntities.ts b/packages/data-store/src/entities/PreMigrationEntities.ts index 6a53b2daf..10dfb6aea 100644 --- a/packages/data-store/src/entities/PreMigrationEntities.ts +++ b/packages/data-store/src/entities/PreMigrationEntities.ts @@ -1,5 +1,5 @@ -import { BaseEntity, Column, Entity, PrimaryColumn } from 'typeorm' -import { KeyType } from "./key.js"; +import { Column, Entity, PrimaryColumn } from 'typeorm' +import { Key } from './key.js' /** * This represents the private key data of keys that were stored by {@link @veramo/data-store#KeyStore} before Veramo @@ -8,16 +8,14 @@ import { KeyType } from "./key.js"; * * @beta This API may change without a BREAKING CHANGE notice. */ -@Entity('key') -export class PreMigrationKey extends BaseEntity { +@Entity('key', ) +export class PreMigrationKey extends Key { + // Key contains all the other columns present needed for successful migrations + @PrimaryColumn() // @ts-ignore kid: string - @Column() - // @ts-ignore - type: KeyType - @Column({ nullable: true }) privateKeyHex?: string } diff --git a/packages/data-store/src/migrations/1.createDatabase.ts b/packages/data-store/src/migrations/1.createDatabase.ts index b9c76c000..68410fc91 100644 --- a/packages/data-store/src/migrations/1.createDatabase.ts +++ b/packages/data-store/src/migrations/1.createDatabase.ts @@ -1,5 +1,7 @@ import { MigrationInterface, QueryRunner, Table } from 'typeorm' import Debug from 'debug' +import { migrationGetTableName } from './migration-functions.js' + const debug = Debug('veramo:data-store:initial-migration') /** @@ -8,14 +10,10 @@ const debug = Debug('veramo:data-store:initial-migration') * @public */ export class CreateDatabase1447159020001 implements MigrationInterface { - async up(queryRunner: QueryRunner): Promise { - function getTableName(givenName: string): string { - return ( - queryRunner.connection.entityMetadatas.find((meta) => meta.givenTableName === givenName)?.tableName || - givenName - ) - } + name = 'CreateDatabase1447159020001' // Used in case this class gets minified, which would change the classname + + async up(queryRunner: QueryRunner): Promise { const dateTimeType: string = queryRunner.connection.driver.mappedDataTypes.createDate as string debug(`creating identifier table`) @@ -23,7 +21,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE UNIQUE INDEX \"IDX_6098cca69c838d91e55ef32fe1\" ON \"identifier\" (\"alias\", \"provider\")", await queryRunner.createTable( new Table({ - name: getTableName('identifier'), + name: migrationGetTableName(queryRunner,'identifier'), columns: [ { name: 'did', type: 'varchar', isPrimary: true }, { name: 'provider', type: 'varchar', isNullable: true }, @@ -46,7 +44,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE TABLE \"key\" (\"kid\" varchar PRIMARY KEY NOT NULL, \"kms\" varchar NOT NULL, \"type\" varchar NOT NULL, \"publicKeyHex\" varchar NOT NULL, \"privateKeyHex\" varchar NOT NULL, \"meta\" text, \"identifierDid\" varchar, CONSTRAINT \"FK_3f40a9459b53adf1729dbd3b787\" FOREIGN KEY (\"identifierDid\") REFERENCES \"identifier\" (\"did\") ON DELETE NO ACTION ON UPDATE NO ACTION)", await queryRunner.createTable( new Table({ - name: getTableName('key'), + name: migrationGetTableName(queryRunner,'key'), columns: [ { name: 'kid', type: 'varchar', isPrimary: true }, { name: 'kms', type: 'varchar' }, @@ -60,7 +58,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { { columnNames: ['identifierDid'], referencedColumnNames: ['did'], - referencedTableName: getTableName('identifier'), + referencedTableName: migrationGetTableName(queryRunner, 'identifier'), }, ], }), @@ -71,7 +69,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE TABLE \"service\" (\"id\" varchar PRIMARY KEY NOT NULL, \"type\" varchar NOT NULL, \"serviceEndpoint\" varchar NOT NULL, \"description\" varchar, \"identifierDid\" varchar, CONSTRAINT \"FK_e16e0280d906951809f95dd09f1\" FOREIGN KEY (\"identifierDid\") REFERENCES \"identifier\" (\"did\") ON DELETE NO ACTION ON UPDATE NO ACTION)", await queryRunner.createTable( new Table({ - name: getTableName('service'), + name: migrationGetTableName(queryRunner, 'service'), columns: [ { name: 'id', type: 'varchar', isPrimary: true }, { name: 'type', type: 'varchar' }, @@ -83,7 +81,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { { columnNames: ['identifierDid'], referencedColumnNames: ['did'], - referencedTableName: getTableName('identifier'), + referencedTableName: migrationGetTableName(queryRunner, 'identifier'), onDelete: 'cascade', }, ], @@ -95,7 +93,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE TABLE \"credential\" (\"hash\" varchar PRIMARY KEY NOT NULL, \"raw\" text NOT NULL, \"id\" varchar, \"issuanceDate\" datetime NOT NULL, \"expirationDate\" datetime, \"context\" text NOT NULL, \"type\" text NOT NULL, \"issuerDid\" varchar, \"subjectDid\" varchar, CONSTRAINT \"FK_123d0977e0976565ee0932c0b9e\" FOREIGN KEY (\"issuerDid\") REFERENCES \"identifier\" (\"did\") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT \"FK_b790831f44e2fa7f9661a017b0a\" FOREIGN KEY (\"subjectDid\") REFERENCES \"identifier\" (\"did\") ON DELETE NO ACTION ON UPDATE NO ACTION)", await queryRunner.createTable( new Table({ - name: getTableName('credential'), + name: migrationGetTableName(queryRunner, 'credential'), columns: [ { name: 'hash', type: 'varchar', isPrimary: true }, { name: 'raw', type: 'text' }, @@ -111,13 +109,13 @@ export class CreateDatabase1447159020001 implements MigrationInterface { { columnNames: ['issuerDid'], referencedColumnNames: ['did'], - referencedTableName: getTableName('identifier'), + referencedTableName: migrationGetTableName(queryRunner, 'identifier'), onDelete: 'cascade', }, { columnNames: ['subjectDid'], referencedColumnNames: ['did'], - referencedTableName: getTableName('identifier'), + referencedTableName: migrationGetTableName(queryRunner, 'identifier'), }, ], }), @@ -128,7 +126,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE TABLE \"claim\" (\"hash\" varchar PRIMARY KEY NOT NULL, \"issuanceDate\" datetime NOT NULL, \"expirationDate\" datetime, \"context\" text NOT NULL, \"credentialType\" text NOT NULL, \"type\" varchar NOT NULL, \"value\" text, \"isObj\" boolean NOT NULL, \"issuerDid\" varchar, \"subjectDid\" varchar, \"credentialHash\" varchar, CONSTRAINT \"FK_d972c73d0f875c0d14c35b33baa\" FOREIGN KEY (\"issuerDid\") REFERENCES \"identifier\" (\"did\") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT \"FK_f411679379d373424100a1c73f4\" FOREIGN KEY (\"subjectDid\") REFERENCES \"identifier\" (\"did\") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT \"FK_3d494b79143de3d0e793883e351\" FOREIGN KEY (\"credentialHash\") REFERENCES \"credential\" (\"hash\") ON DELETE NO ACTION ON UPDATE NO ACTION)", await queryRunner.createTable( new Table({ - name: getTableName('claim'), + name: migrationGetTableName(queryRunner, 'claim'), columns: [ { name: 'hash', type: 'varchar', isPrimary: true }, { name: 'issuanceDate', type: dateTimeType }, @@ -146,18 +144,18 @@ export class CreateDatabase1447159020001 implements MigrationInterface { { columnNames: ['issuerDid'], referencedColumnNames: ['did'], - referencedTableName: getTableName('identifier'), + referencedTableName: migrationGetTableName(queryRunner, 'identifier'), onDelete: 'cascade', }, { columnNames: ['subjectDid'], referencedColumnNames: ['did'], - referencedTableName: getTableName('identifier'), + referencedTableName: migrationGetTableName(queryRunner, 'identifier'), }, { columnNames: ['credentialHash'], referencedColumnNames: ['hash'], - referencedTableName: getTableName('credential'), + referencedTableName: migrationGetTableName(queryRunner, 'credential'), onDelete: 'cascade', }, ], @@ -169,7 +167,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE TABLE \"presentation\" (\"hash\" varchar PRIMARY KEY NOT NULL, \"raw\" text NOT NULL, \"id\" varchar, \"issuanceDate\" datetime NOT NULL, \"expirationDate\" datetime, \"context\" text NOT NULL, \"type\" text NOT NULL, \"holderDid\" varchar, CONSTRAINT \"FK_a5e418449d9f527776a3bd0ca61\" FOREIGN KEY (\"holderDid\") REFERENCES \"identifier\" (\"did\") ON DELETE NO ACTION ON UPDATE NO ACTION)", await queryRunner.createTable( new Table({ - name: getTableName('presentation'), + name: migrationGetTableName(queryRunner, 'presentation'), columns: [ { name: 'hash', type: 'varchar', isPrimary: true }, { name: 'raw', type: 'text' }, @@ -184,7 +182,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { { columnNames: ['holderDid'], referencedColumnNames: ['did'], - referencedTableName: getTableName('identifier'), + referencedTableName: migrationGetTableName(queryRunner, 'identifier'), onDelete: 'cascade', }, ], @@ -196,7 +194,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE TABLE \"message\" (\"id\" varchar PRIMARY KEY NOT NULL, \"saveDate\" datetime NOT NULL DEFAULT (datetime('now')), \"updateDate\" datetime NOT NULL DEFAULT (datetime('now')), \"createdAt\" datetime, \"expiresAt\" datetime, \"threadId\" varchar, \"type\" varchar NOT NULL, \"raw\" varchar, \"data\" text, \"replyTo\" text, \"replyUrl\" varchar, \"metaData\" text, \"fromDid\" varchar, \"toDid\" varchar, CONSTRAINT \"FK_63bf73143b285c727bd046e6710\" FOREIGN KEY (\"fromDid\") REFERENCES \"identifier\" (\"did\") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT \"FK_1a666b2c29bb2b68d91259f55df\" FOREIGN KEY (\"toDid\") REFERENCES \"identifier\" (\"did\") ON DELETE NO ACTION ON UPDATE NO ACTION)", await queryRunner.createTable( new Table({ - name: getTableName('message'), + name: migrationGetTableName(queryRunner, 'message'), columns: [ { name: 'id', type: 'varchar', isPrimary: true }, { name: 'saveDate', type: dateTimeType }, @@ -217,12 +215,12 @@ export class CreateDatabase1447159020001 implements MigrationInterface { { columnNames: ['fromDid'], referencedColumnNames: ['did'], - referencedTableName: getTableName('identifier'), + referencedTableName: migrationGetTableName(queryRunner, 'identifier'), }, { columnNames: ['toDid'], referencedColumnNames: ['did'], - referencedTableName: getTableName('identifier'), + referencedTableName: migrationGetTableName(queryRunner, 'identifier'), }, ], }), @@ -235,7 +233,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE INDEX \"IDX_3a460e48557bad5564504ddad9\" ON \"presentation_verifier_identifier\" (\"identifierDid\")", await queryRunner.createTable( new Table({ - name: getTableName('presentation_verifier_identifier'), + name: migrationGetTableName(queryRunner, 'presentation_verifier_identifier'), columns: [ { name: 'presentationHash', type: 'varchar', isPrimary: true }, { name: 'identifierDid', type: 'varchar', isPrimary: true }, @@ -249,13 +247,13 @@ export class CreateDatabase1447159020001 implements MigrationInterface { { columnNames: ['presentationHash'], referencedColumnNames: ['hash'], - referencedTableName: getTableName('presentation'), + referencedTableName: migrationGetTableName(queryRunner, 'presentation'), onDelete: 'cascade', }, { columnNames: ['identifierDid'], referencedColumnNames: ['did'], - referencedTableName: getTableName('identifier'), + referencedTableName: migrationGetTableName(queryRunner, 'identifier'), onDelete: 'cascade', }, ], @@ -269,7 +267,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE INDEX \"IDX_ef88f92988763fee884c37db63\" ON \"presentation_credentials_credential\" (\"credentialHash\")", await queryRunner.createTable( new Table({ - name: getTableName('presentation_credentials_credential'), + name: migrationGetTableName(queryRunner, 'presentation_credentials_credential'), columns: [ { name: 'presentationHash', type: 'varchar', isPrimary: true }, { name: 'credentialHash', type: 'varchar', isPrimary: true }, @@ -283,13 +281,13 @@ export class CreateDatabase1447159020001 implements MigrationInterface { { columnNames: ['presentationHash'], referencedColumnNames: ['hash'], - referencedTableName: getTableName('presentation'), + referencedTableName: migrationGetTableName(queryRunner, 'presentation'), onDelete: 'cascade', }, { columnNames: ['credentialHash'], referencedColumnNames: ['hash'], - referencedTableName: getTableName('credential'), + referencedTableName: migrationGetTableName(queryRunner, 'credential'), onDelete: 'cascade', }, ], @@ -303,7 +301,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE INDEX \"IDX_a13b5cf828c669e61faf489c18\" ON \"message_presentations_presentation\" (\"presentationHash\")", await queryRunner.createTable( new Table({ - name: getTableName('message_presentations_presentation'), + name: migrationGetTableName(queryRunner, 'message_presentations_presentation'), columns: [ { name: 'messageId', type: 'varchar', isPrimary: true }, { name: 'presentationHash', type: 'varchar', isPrimary: true }, @@ -317,13 +315,13 @@ export class CreateDatabase1447159020001 implements MigrationInterface { { columnNames: ['messageId'], referencedColumnNames: ['id'], - referencedTableName: getTableName('message'), + referencedTableName: migrationGetTableName(queryRunner, 'message'), onDelete: 'cascade', }, { columnNames: ['presentationHash'], referencedColumnNames: ['hash'], - referencedTableName: getTableName('presentation'), + referencedTableName: migrationGetTableName(queryRunner, 'presentation'), onDelete: 'cascade', }, ], @@ -337,7 +335,7 @@ export class CreateDatabase1447159020001 implements MigrationInterface { // "CREATE INDEX \"IDX_8ae8195a94b667b185d2c023e3\" ON \"message_credentials_credential\" (\"credentialHash\")", await queryRunner.createTable( new Table({ - name: getTableName('message_credentials_credential'), + name: migrationGetTableName(queryRunner, 'message_credentials_credential'), columns: [ { name: 'messageId', type: 'varchar', isPrimary: true }, { name: 'credentialHash', type: 'varchar', isPrimary: true }, @@ -351,13 +349,13 @@ export class CreateDatabase1447159020001 implements MigrationInterface { { columnNames: ['messageId'], referencedColumnNames: ['id'], - referencedTableName: getTableName('message'), + referencedTableName: migrationGetTableName(queryRunner, 'message'), onDelete: 'cascade', }, { columnNames: ['credentialHash'], referencedColumnNames: ['hash'], - referencedTableName: getTableName('credential'), + referencedTableName: migrationGetTableName(queryRunner, 'credential'), onDelete: 'cascade', }, ], diff --git a/packages/data-store/src/migrations/2.simplifyRelations.ts b/packages/data-store/src/migrations/2.simplifyRelations.ts index 9e353fb27..b44f0920d 100644 --- a/packages/data-store/src/migrations/2.simplifyRelations.ts +++ b/packages/data-store/src/migrations/2.simplifyRelations.ts @@ -1,5 +1,6 @@ import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm' -import Debug from 'debug' +import { migrationGetExistingTableByName } from './migration-functions.js' +import { PreMigrationKey } from '../entities/PreMigrationEntities.js' /** * Fix inconsistencies between Entity data and column data. @@ -7,23 +8,21 @@ import Debug from 'debug' * @public */ export class SimplifyRelations1447159020002 implements MigrationInterface { + + name = 'SimplifyRelations1447159020002' // Used in case this class gets minified, which would change the classname + async up(queryRunner: QueryRunner): Promise { - function getTableName(givenName: string): string { - return ( - queryRunner.connection.entityMetadatas.find((meta) => meta.givenTableName === givenName)?.tableName || - givenName - ) - } await queryRunner.changeColumn( - getTableName('key'), + migrationGetExistingTableByName(queryRunner, 'PreMigrationKey', true), 'identifierDid', new TableColumn({ name: 'identifierDid', type: 'varchar', isNullable: true }), ) await queryRunner.changeColumn( - getTableName('service'), + migrationGetExistingTableByName(queryRunner, 'service'), 'identifierDid', new TableColumn({ name: 'identifierDid', type: 'varchar', isNullable: true }), ) + } async down(queryRunner: QueryRunner): Promise { diff --git a/packages/data-store/src/migrations/3.createPrivateKeyStorage.ts b/packages/data-store/src/migrations/3.createPrivateKeyStorage.ts index 94a82391e..416d64630 100644 --- a/packages/data-store/src/migrations/3.createPrivateKeyStorage.ts +++ b/packages/data-store/src/migrations/3.createPrivateKeyStorage.ts @@ -2,6 +2,8 @@ import { MigrationInterface, QueryRunner, Table, TableColumn } from 'typeorm' import { PrivateKey } from '../index.js' import { PreMigrationKey } from '../entities/PreMigrationEntities.js' import Debug from 'debug' +import { migrationGetExistingTableByName, migrationGetTableName } from './migration-functions.js' + const debug = Debug('veramo:data-store:migrate-private-keys') /** @@ -10,18 +12,15 @@ const debug = Debug('veramo:data-store:migrate-private-keys') * @public */ export class CreatePrivateKeyStorage1629293428674 implements MigrationInterface { + + name = 'CreatePrivateKeyStorage1629293428674' // Used in case this class gets minified, which would change the classname + async up(queryRunner: QueryRunner): Promise { - function getTableName(givenName: string): string { - return ( - queryRunner.connection.entityMetadatas.find((meta) => meta.givenTableName === givenName)?.tableName || - givenName - ) - } // 1.create new table debug(`creating new private-key table`) await queryRunner.createTable( new Table({ - name: getTableName('private-key'), + name: migrationGetTableName(queryRunner, 'private-key'), columns: [ { name: 'alias', @@ -54,23 +53,19 @@ export class CreatePrivateKeyStorage1629293428674 implements MigrationInterface await queryRunner.manager .createQueryBuilder() .insert() - .into(getTableName('private-key')) + .into(migrationGetTableName(queryRunner, 'private-key')) .values(privKeys) .execute() // 3. drop old column debug(`dropping privKeyHex column from old key table`) - await queryRunner.dropColumn(getTableName('key'), 'privateKeyHex') + await queryRunner.dropColumn(migrationGetExistingTableByName(queryRunner, 'PreMigrationKey', true), 'privateKeyHex') //4. done debug(`migrated ${privKeys.length} keys to private key storage`) + } async down(queryRunner: QueryRunner): Promise { - function getTableName(givenName: string): string { - return ( - queryRunner.connection.entityMetadatas.find((meta) => meta.givenTableName === givenName)?.tableName || - givenName - ) - } + // 1. add old column back debug(`adding back privateKeyHex column to key table`) await queryRunner.addColumn( @@ -95,7 +90,7 @@ export class CreatePrivateKeyStorage1629293428674 implements MigrationInterface } debug(`dropping private-key table`) // 3. drop the new private key table - await queryRunner.dropTable(getTableName('private-key')) + await queryRunner.dropTable(migrationGetExistingTableByName(queryRunner, 'private-key')) // 4. done debug(`rolled back ${keys.length} keys`) } diff --git a/packages/data-store/src/migrations/4.allowNullVPIssuanceDate.ts b/packages/data-store/src/migrations/4.allowNullVPIssuanceDate.ts index 9f2445f96..a1fa6cc8b 100644 --- a/packages/data-store/src/migrations/4.allowNullVPIssuanceDate.ts +++ b/packages/data-store/src/migrations/4.allowNullVPIssuanceDate.ts @@ -1,6 +1,7 @@ import { MigrationInterface, QueryRunner } from 'typeorm' import { Presentation } from '../index.js' import Debug from 'debug' +import { migrationGetExistingTableByName } from './migration-functions.js' const debug = Debug('veramo:data-store:migrate-presentation-issuance-date') @@ -10,12 +11,8 @@ const debug = Debug('veramo:data-store:migrate-presentation-issuance-date') * @public */ export class AllowNullIssuanceDateForPresentations1637237492913 implements MigrationInterface { - private getTableName(givenName: string, queryRunner: QueryRunner): string { - return ( - queryRunner.connection.entityMetadatas.find((meta) => meta.givenTableName === givenName)?.tableName || - givenName - ) - } + + name = 'AllowNullIssuanceDateForPresentations1637237492913' // Used in case this class gets minified, which would change the classname async up(queryRunner: QueryRunner): Promise { if (queryRunner.connection.driver.options.type === 'sqlite') { @@ -26,9 +23,8 @@ export class AllowNullIssuanceDateForPresentations1637237492913 implements Migra await queryRunner.startTransaction() } - const tableName = this.getTableName('presentation', queryRunner) // update issuanceDate column - let table = await queryRunner.getTable(tableName) + const table = migrationGetExistingTableByName(queryRunner, 'presentation') const oldColumn = table?.findColumnByName('issuanceDate')! const newColumn = oldColumn.clone() newColumn.isNullable = true @@ -53,8 +49,9 @@ export class AllowNullIssuanceDateForPresentations1637237492913 implements Migra await queryRunner.query('PRAGMA foreign_keys=off') await queryRunner.startTransaction() } - const tableName = this.getTableName('presentation', queryRunner) - debug(`DOWN update NULL 'issuanceDate' with FAKE data for '${tableName}' table`) + + const table = migrationGetExistingTableByName(queryRunner, 'presentation') + debug(`DOWN update NULL 'issuanceDate' with FAKE data for '${table.name}' table`) await queryRunner.manager .createQueryBuilder() .update(Presentation) @@ -62,7 +59,7 @@ export class AllowNullIssuanceDateForPresentations1637237492913 implements Migra .where('issuanceDate is NULL') .execute() // update issuanceDate column - let table = await queryRunner.getTable(tableName) + const oldColumn = table?.findColumnByName('issuanceDate')! const newColumn = oldColumn.clone() newColumn.isNullable = false diff --git a/packages/data-store/src/migrations/index.ts b/packages/data-store/src/migrations/index.ts index 571b20417..45bc0d4e8 100644 --- a/packages/data-store/src/migrations/index.ts +++ b/packages/data-store/src/migrations/index.ts @@ -3,6 +3,14 @@ import { SimplifyRelations1447159020002 } from './2.simplifyRelations.js' import { CreatePrivateKeyStorage1629293428674 } from './3.createPrivateKeyStorage.js' import { AllowNullIssuanceDateForPresentations1637237492913 } from './4.allowNullVPIssuanceDate.js' + +/** + * Allow others to use shared migration functions if they extend Veramo + * + * @public + */ +export * from './migration-functions.js' + /** * The migrations array that SHOULD be used when initializing a TypeORM database connection. * @@ -10,6 +18,7 @@ import { AllowNullIssuanceDateForPresentations1637237492913 } from './4.allowNul * * @public */ + export const migrations = [ CreateDatabase1447159020001, SimplifyRelations1447159020002, diff --git a/packages/data-store/src/migrations/migration-functions.ts b/packages/data-store/src/migrations/migration-functions.ts new file mode 100644 index 000000000..225016606 --- /dev/null +++ b/packages/data-store/src/migrations/migration-functions.ts @@ -0,0 +1,50 @@ +import { QueryRunner, Table } from 'typeorm' + +/** + * Get an existing table by name. Checks against givenTableName first, and tableName next. Throws an error if not found + * + * @param queryRunner The query runner object to use for querying + * @param givenName The given name of the table to search for + * @param strictClassName Whether the table name should strictly match the given name + * + * @public + */ +export function migrationGetExistingTableByName(queryRunner: QueryRunner, givenName: string, strictClassName?: boolean): Table { + const table = migrationGetTableByNameImpl(queryRunner, givenName, strictClassName) + if (!table) { + throw Error(`Could not find table with name ${givenName}`) + } + return table +} + +/** + * Get an existing table by name. Checks against givenTableName first, and tableName next. Returns undefined if not found + * + * @param queryRunner The query runner object to use for querying + * @param givenName The given name of the table to search for + * @param strictClassName Whether the table name should strictly match the given name + * + * @private + */ +function migrationGetTableByNameImpl(queryRunner: QueryRunner, givenName: string, strictClassName?: boolean): Table | undefined { + let entityMetadata = queryRunner.connection.entityMetadatas.find((meta) => !!strictClassName ? meta.name === givenName : meta.givenTableName === givenName) + if (!entityMetadata && !strictClassName) { + // We are doing this separately as we don't want the above filter to use an or expression potentially matching first on tableName instead of givenTableName + entityMetadata = queryRunner.connection.entityMetadatas.find((meta) => meta.tableName === givenName) + } + + return entityMetadata ? Table.create(entityMetadata, queryRunner.connection.driver) : undefined +} + +/** + * Get a table name. Checks against givenTableName first, and tableName next from existing tables. Then returns the name. If not found returns the givenName argument + * + * @param queryRunner The query runner object to use for querying + * @param givenName The given name of the table to search for + * @param strictClassName Whether the table name should strictly match the given name + * @public + */ +export function migrationGetTableName(queryRunner: QueryRunner, givenName: string, strictClassName?: boolean): string { + const table = migrationGetTableByNameImpl(queryRunner, givenName, strictClassName) + return !!table ? table.name : givenName +}