diff --git a/packages/cli/src/databases/entities/AbstractEntity.ts b/packages/cli/src/databases/entities/AbstractEntity.ts index 91256946198204..92b90a64ea952f 100644 --- a/packages/cli/src/databases/entities/AbstractEntity.ts +++ b/packages/cli/src/databases/entities/AbstractEntity.ts @@ -1,11 +1,6 @@ -import { - BeforeInsert, - BeforeUpdate, - CreateDateColumn, - PrimaryColumn, - UpdateDateColumn, -} from 'typeorm'; -import { IsDate, IsOptional } from 'class-validator'; +import type { ColumnOptions } from 'typeorm'; +import { BeforeInsert, BeforeUpdate, Column, PrimaryColumn } from 'typeorm'; +import { IsOptional } from 'class-validator'; import config from '@/config'; import { generateNanoId } from '../utils/generators'; @@ -21,9 +16,10 @@ const timestampSyntax = { export const jsonColumnType = dbType === 'sqlite' ? 'simple-json' : 'json'; export const datetimeColumnType = dbType === 'postgresdb' ? 'timestamptz' : 'datetime'; -const tsColumnOptions = { +const tsColumnOptions: ColumnOptions = { precision: 3, default: () => timestampSyntax, + type: datetimeColumnType, }; type Constructor = new (...args: any[]) => T; @@ -45,17 +41,15 @@ function mixinStringId>(base: T) { function mixinTimestamps>(base: T) { class Derived extends base { - @CreateDateColumn(tsColumnOptions) + @Column(tsColumnOptions) @IsOptional() // ignored by validation because set at DB level - @IsDate() createdAt: Date; - @UpdateDateColumn({ + @Column({ ...tsColumnOptions, onUpdate: timestampSyntax, }) @IsOptional() // ignored by validation because set at DB level - @IsDate() updatedAt: Date; @BeforeUpdate() diff --git a/packages/cli/src/databases/migrations/postgresdb/1692207852593-MigrateToTimestampZ1692207852593.ts b/packages/cli/src/databases/migrations/postgresdb/1692207852593-MigrateToTimestampZ1692207852593.ts new file mode 100644 index 00000000000000..bee95a59c23f66 --- /dev/null +++ b/packages/cli/src/databases/migrations/postgresdb/1692207852593-MigrateToTimestampZ1692207852593.ts @@ -0,0 +1,42 @@ +import type { IrreversibleMigration, MigrationContext } from '@/databases/types'; + +const defaultTimestampColumns = ['createdAt', 'updatedAt']; +const tablesWithDefaultTimestamps = [ + 'auth_identity', + 'credentials_entity', + 'event_destinations', + 'installed_packages', + 'role', + 'shared_credentials', + 'shared_workflow', + 'tag_entity', + 'user', + 'workflow_entity', +]; + +const additionalColumns = { + auth_provider_sync_history: ['endedAt', 'startedAt'], + execution_entity: ['startedAt', 'stoppedAt', 'waitTill'], + workflow_statistics: ['latestEvent'], +}; + +export class MigrateToTimestampZ1692207852593 implements IrreversibleMigration { + async up({ queryRunner, tablePrefix }: MigrationContext) { + // You cannot define a TIMESTAMPTZ column with a specific precision for fractional seconds other than 6. + const changeColumnType = async (tableName: string, columnName: string) => + queryRunner.query( + `ALTER TABLE "${tablePrefix}${tableName}" ALTER COLUMN "${columnName}" TYPE TIMESTAMPTZ(3)`, + ); + + for (const tableName of tablesWithDefaultTimestamps) { + for (const columnName of defaultTimestampColumns) { + await changeColumnType(tableName, columnName); + } + } + for (const [tableName, columnNames] of Object.entries(additionalColumns)) { + for (const columnName of columnNames) { + await changeColumnType(tableName, columnName); + } + } + } +} diff --git a/packages/cli/src/databases/migrations/postgresdb/index.ts b/packages/cli/src/databases/migrations/postgresdb/index.ts index 554bb1311483a6..773a93b424e40a 100644 --- a/packages/cli/src/databases/migrations/postgresdb/index.ts +++ b/packages/cli/src/databases/migrations/postgresdb/index.ts @@ -42,6 +42,7 @@ import { RemoveSkipOwnerSetup1681134145997 } from './1681134145997-RemoveSkipOwn import { RemoveResetPasswordColumns1690000000030 } from '../common/1690000000030-RemoveResetPasswordColumns'; import { AddMissingPrimaryKeyOnExecutionData1690787606731 } from './1690787606731-AddMissingPrimaryKeyOnExecutionData'; import { CreateWorkflowNameIndex1691088862123 } from '../common/1691088862123-CreateWorkflowNameIndex'; +import { MigrateToTimestampZ1692207852593 } from './1692207852593-MigrateToTimestampZ1692207852593'; export const postgresMigrations: Migration[] = [ InitialMigration1587669153312, @@ -87,4 +88,5 @@ export const postgresMigrations: Migration[] = [ RemoveResetPasswordColumns1690000000030, AddMissingPrimaryKeyOnExecutionData1690787606731, CreateWorkflowNameIndex1691088862123, + MigrateToTimestampZ1692207852593, ];