diff --git a/scripts/migrate-db.js b/scripts/migrate-db.js index 0984901f..88e5336f 100644 --- a/scripts/migrate-db.js +++ b/scripts/migrate-db.js @@ -25,9 +25,9 @@ function success(msg) { console.log(chalk.greenBright(`✓ ${msg}`)); } -// function error(msg) { -// console.log(chalk.redBright(`✗ ${msg}`)); -// } +function error(msg) { + console.log(chalk.redBright(`✗ ${msg}`)); +} async function checkEnv() { if (!process.env.DATABASE_URL) { @@ -48,28 +48,19 @@ async function checkConnection() { } async function checkV1Tables(databaseType) { - const updateV1 = + try { await prisma.$queryRaw`select * from _prisma_migrations where migration_name = '04_add_uuid' and finished_at IS NOT NULL`; - if (updateV1.length > 0) { console.log('Preparing v1 tables for migration'); // alter v1 tables - if (databaseType === 'postgresql') { - await dropV1Keys(); - } - + await dropV1Keys(databaseType); await dropV1Indexes(databaseType); await renameV1Tables(databaseType); - } - - // check for V1 renamed tables - try { - await prisma.$queryRaw`select * from v1_account limit 1`; success('Database v1 tables ready for migration.'); } catch (e) { - throw new Error('Database v1 tables not found.'); + error('Database v1 tables is not up to date.'); } } @@ -85,32 +76,83 @@ async function checkV2Tables() { // run v2 prisma migration steps await runSqlFile('../prisma/migrations/01_init/migration.sql'); console.log(execSync('prisma migrate resolve --applied 01_init').toString()); - console.log(execSync('prisma migrate deploy').toString()); + // console.log(execSync('prisma migrate deploy').toString()); } } -async function migrateData() { +async function checkMigrationReady() { + try { + await prisma.$queryRaw`select * from website_event limit 1`; + await prisma.$queryRaw`select * from v1_account limit 1`; + + success('Database is ready for migration.'); + } catch (e) { + throw new Error('Database is not ready for migration.'); + } +} + +async function migrateData(databaseType) { + const filePath = `../db/${databaseType}/migration_v2.sql`; console.log('Starting v2 data migration. Please do no cancel this process, it may take a while.'); - await runSqlFile('../db/postgresql/migration_v2.sql'); + await runSqlFile(filePath); success('Data migration from V1 to V2 tables completed.'); } -async function dropV1Keys() { +async function dropV1Keys(databaseType) { try { // drop keys - await prisma.$transaction([ - prisma.$executeRaw`ALTER TABLE IF EXISTS "_prisma_migrations" DROP CONSTRAINT IF EXISTS "_prisma_migrations_pkey" cascade;`, - prisma.$executeRaw`ALTER TABLE IF EXISTS "account" DROP CONSTRAINT IF EXISTS "account_pkey" cascade;`, - prisma.$executeRaw`ALTER TABLE IF EXISTS "event" DROP CONSTRAINT IF EXISTS "event_pkey" cascade;`, - prisma.$executeRaw`ALTER TABLE IF EXISTS "session" DROP CONSTRAINT IF EXISTS "session_pkey" cascade;`, - prisma.$executeRaw`ALTER TABLE IF EXISTS "website" DROP CONSTRAINT IF EXISTS "website_pkey" cascade;`, - ]); + if (databaseType === 'postgresql') { + await prisma.$transaction([ + prisma.$executeRaw`ALTER TABLE IF EXISTS _prisma_migrations DROP CONSTRAINT IF EXISTS _prisma_migrations_pkey CASCADE;`, + prisma.$executeRaw`ALTER TABLE IF EXISTS account DROP CONSTRAINT IF EXISTS account_pkey CASCADE;`, + prisma.$executeRaw`ALTER TABLE IF EXISTS event DROP CONSTRAINT IF EXISTS event_pkey CASCADE;`, + prisma.$executeRaw`ALTER TABLE IF EXISTS session DROP CONSTRAINT IF EXISTS session_pkey CASCADE;`, + prisma.$executeRaw`ALTER TABLE IF EXISTS website DROP CONSTRAINT IF EXISTS website_pkey CASCADE;`, + ]); + } else { + await prisma.$transaction([ + prisma.$executeRaw`ALTER TABLE session DROP FOREIGN KEY session_website_id_fkey;`, + prisma.$executeRaw`ALTER TABLE website DROP FOREIGN KEY website_user_id_fkey;`, + ]); + } success('Dropped v1 database keys.'); } catch (e) { console.log(e); - throw new Error('Failed to drop v1 database keys.'); + error('Failed to drop v1 database keys.'); + process.exit(1); + } +} + +async function dropV1Indexes(databaseType) { + try { + // drop indexes + if (databaseType === 'postgresql') { + await prisma.$transaction([ + prisma.$executeRaw`DROP INDEX IF EXISTS session_session_id_key;`, + prisma.$executeRaw`DROP INDEX IF EXISTS session_created_at_idx;`, + prisma.$executeRaw`DROP INDEX IF EXISTS session_website_id_idx;`, + prisma.$executeRaw`DROP INDEX IF EXISTS website_website_id_key;`, + prisma.$executeRaw`DROP INDEX IF EXISTS website_share_id_key;`, + prisma.$executeRaw`DROP INDEX IF EXISTS website_created_at_idx;`, + prisma.$executeRaw`DROP INDEX IF EXISTS website_share_id_idx;`, + prisma.$executeRaw`DROP INDEX IF EXISTS website_user_id_idx;`, + ]); + } else { + await prisma.$transaction([ + prisma.$executeRaw`DROP INDEX session_created_at_idx ON session;`, + prisma.$executeRaw`DROP INDEX session_website_id_idx ON session;`, + prisma.$executeRaw`DROP INDEX website_user_id_idx ON website;`, + prisma.$executeRaw`DROP INDEX website_share_id_key ON website;`, + ]); + } + + success('Dropped v1 database indexes.'); + } catch (e) { + console.log(e); + error('Failed to drop v1 database indexes.'); + process.exit(1); } } @@ -119,13 +161,13 @@ async function renameV1Tables(databaseType) { // rename tables if (databaseType === 'postgresql') { await prisma.$transaction([ - prisma.$executeRaw`ALTER TABLE IF EXISTS "_prisma_migrations" RENAME TO "v1_prisma_migrations";`, - prisma.$executeRaw`ALTER TABLE IF EXISTS "account" RENAME TO "v1_account";`, - prisma.$executeRaw`ALTER TABLE IF EXISTS "event" RENAME TO "v1_event";`, - prisma.$executeRaw`ALTER TABLE IF EXISTS "event_data" RENAME TO "v1_event_data";`, - prisma.$executeRaw`ALTER TABLE IF EXISTS "pageview" RENAME TO "v1_pageview";`, - prisma.$executeRaw`ALTER TABLE IF EXISTS "session" RENAME TO "v1_session";`, - prisma.$executeRaw`ALTER TABLE IF EXISTS "website" RENAME TO "v1_website";`, + prisma.$executeRaw`ALTER TABLE IF EXISTS _prisma_migrations RENAME TO v1_prisma_migrations;`, + prisma.$executeRaw`ALTER TABLE IF EXISTS account RENAME TO v1_account;`, + prisma.$executeRaw`ALTER TABLE IF EXISTS event RENAME TO v1_event;`, + prisma.$executeRaw`ALTER TABLE IF EXISTS event_data RENAME TO v1_event_data;`, + prisma.$executeRaw`ALTER TABLE IF EXISTS pageview RENAME TO v1_pageview;`, + prisma.$executeRaw`ALTER TABLE IF EXISTS session RENAME TO v1_session;`, + prisma.$executeRaw`ALTER TABLE IF EXISTS website RENAME TO v1_website;`, ]); } else { await prisma.$transaction([ @@ -142,39 +184,8 @@ async function renameV1Tables(databaseType) { success('Renamed v1 database tables.'); } catch (e) { console.log(e); - throw new Error('Failed to rename v1 database tables.'); - } -} - -async function dropV1Indexes(databaseType) { - try { - // drop indexes - if (databaseType === 'postgresql') { - await prisma.$transaction([ - prisma.$executeRaw`DROP INDEX IF EXISTS "session_session_id_key";`, - prisma.$executeRaw`DROP INDEX IF EXISTS "session_created_at_idx";`, - prisma.$executeRaw`DROP INDEX IF EXISTS "session_website_id_idx";`, - prisma.$executeRaw`DROP INDEX IF EXISTS "website_website_id_key";`, - prisma.$executeRaw`DROP INDEX IF EXISTS "website_share_id_key";`, - prisma.$executeRaw`DROP INDEX IF EXISTS "website_created_at_idx";`, - prisma.$executeRaw`DROP INDEX IF EXISTS "website_share_id_idx";`, - prisma.$executeRaw`DROP INDEX IF EXISTS "website_user_id_idx";`, - ]); - } else { - await prisma.$transaction([ - prisma.$executeRaw`ALTER TABLE session DROP FOREIGN KEY session_website_id_fkey;`, - prisma.$executeRaw`DROP INDEX session_created_at_idx ON session;`, - prisma.$executeRaw`DROP INDEX session_website_id_idx ON session;`, - prisma.$executeRaw`ALTER TABLE website DROP FOREIGN KEY website_user_id_fkey;`, - prisma.$executeRaw`DROP INDEX website_user_id_idx ON website;`, - prisma.$executeRaw`DROP INDEX website_share_id_key ON website;`, - ]); - } - - success('Dropped v1 database indexes.'); - } catch (e) { - console.log(e); - throw new Error('Failed to drop v1 database indexes.'); + error('Failed to rename v1 database tables.'); + process.exit(1); } } @@ -198,17 +209,18 @@ async function deleteV1Tables() { try { // drop tables await prisma.$transaction([ - prisma.$executeRaw`DROP TABLE IF EXISTS "v1_prisma_migrations";`, - prisma.$executeRaw`DROP TABLE IF EXISTS "v1_account";`, - prisma.$executeRaw`DROP TABLE IF EXISTS "v1_event";`, - prisma.$executeRaw`DROP TABLE IF EXISTS "v1_event_data";`, - prisma.$executeRaw`DROP TABLE IF EXISTS "v1_pageview";`, - prisma.$executeRaw`DROP TABLE IF EXISTS "v1_session";`, - prisma.$executeRaw`DROP TABLE IF EXISTS "v1_website";`, + prisma.$executeRaw`DROP TABLE IF EXISTS v1_prisma_migrations;`, + prisma.$executeRaw`DROP TABLE IF EXISTS v1_event_data;`, + prisma.$executeRaw`DROP TABLE IF EXISTS v1_event;`, + prisma.$executeRaw`DROP TABLE IF EXISTS v1_pageview;`, + prisma.$executeRaw`DROP TABLE IF EXISTS v1_session;`, + prisma.$executeRaw`DROP TABLE IF EXISTS v1_website;`, + prisma.$executeRaw`DROP TABLE IF EXISTS v1_account;`, ]); success('Dropped v1 database tables.'); } catch (e) { + console.log(e); throw new Error('Failed to drop v1 database tables.'); } } @@ -247,13 +259,14 @@ async function runSqlFile(filePath) { checkConnection, checkV1Tables, checkV2Tables, + checkMigrationReady, migrateData, deleteV1TablesPrompt, ]) { try { - fn.name === 'checkV1Tables' ? await fn(databaseType) : await fn(); + ['checkV1Tables', 'migrateData'].includes(fn.name) ? await fn(databaseType) : await fn(); } catch (e) { - console.log(chalk.red(`✗ ${e.message}`)); + error(e.message); err = true; } finally { await prisma.$disconnect();