From 7c0db0633fe434025a09f880f38423414f8ac997 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Fri, 20 Jan 2023 14:21:11 -0800 Subject: [PATCH 1/2] update check-db, add pgcrypto extension if not exists on init migration --- .../migrations/01_init/migration.sql | 3 + scripts/check-db.js | 84 +++++++++---------- 2 files changed, 42 insertions(+), 45 deletions(-) diff --git a/db/postgresql/migrations/01_init/migration.sql b/db/postgresql/migrations/01_init/migration.sql index dc46c0c4..578e6f9c 100644 --- a/db/postgresql/migrations/01_init/migration.sql +++ b/db/postgresql/migrations/01_init/migration.sql @@ -1,3 +1,6 @@ +-- CreateExtension +CREATE EXTENSION IF NOT EXISTS "pgcrypto"; + -- CreateTable CREATE TABLE "user" ( "user_id" UUID NOT NULL, diff --git a/scripts/check-db.js b/scripts/check-db.js index 9b5a47a8..87e22367 100644 --- a/scripts/check-db.js +++ b/scripts/check-db.js @@ -2,14 +2,25 @@ require('dotenv').config(); const { PrismaClient } = require('@prisma/client'); const chalk = require('chalk'); -const spawn = require('cross-spawn'); const { execSync } = require('child_process'); +const semver = require('semver'); if (process.env.SKIP_DB_CHECK) { console.log('Skipping database check.'); process.exit(0); } +function getDatabaseType(url = process.env.DATABASE_URL) { + const type = process.env.DATABASE_TYPE || (url && url.split(':')[0]); + + if (type === 'postgres') { + return 'postgresql'; + } + + return type; +} + +const databaseType = getDatabaseType(); const prisma = new PrismaClient(); function success(msg) { @@ -38,64 +49,47 @@ async function checkConnection() { } } -async function checkTables() { +async function checkDatabaseVersion(databaseType) { + const query = await prisma.$queryRaw`select version() version`; + const version = semver.valid(semver.coerce(query[0].version)); + + const minVersion = databaseType === 'postgresql' ? '9.4.0' : '5.6.0'; + + if (semver.lt(version, minVersion)) { + throw new Error( + `Database version is not compatible. Please upgrade to ${databaseType} version to ${minVersion} or greater`, + ); + } + + success('Database version check successful.'); +} + +async function checkV1Tables() { try { - await prisma.$queryRaw`select * from user limit 1`; + await prisma.$queryRaw`select * from account limit 1`; - success('Database tables found.'); + console.log('Umami v1 tables detected. To upgrade from v1 to v2 run'); + console.log('npx @umami/migrate-v1-v2'); + + process.exit(0); } catch (e) { - error('Database tables not found.'); - console.log('Adding tables...'); - - console.log(execSync('prisma migrate deploy').toString()); + // Ignore } } -async function run(cmd, args) { - const buffer = []; - const proc = spawn(cmd, args); - - return new Promise((resolve, reject) => { - proc.stdout.on('data', data => buffer.push(data)); - - proc.on('error', () => { - reject(new Error('Failed to run Prisma.')); - }); - - proc.on('exit', () => resolve(buffer.join(''))); - }); -} - -async function checkMigrations() { - const output = await run('prisma', ['migrate', 'status']); - - console.log(output); - - const missingMigrations = output.includes('have not yet been applied'); - const missingInitialMigration = - output.includes('01_init') && !output.includes('The last common migration is: 01_init'); - const notManaged = output.includes('The current database is not managed'); - - if (notManaged || missingMigrations) { - console.log('Running update...'); - - if (missingInitialMigration) { - console.log(execSync('prisma migrate resolve --applied "01_init"').toString()); - } - - console.log(execSync('prisma migrate deploy').toString()); - } +async function applyMigration() { + console.log(execSync('prisma migrate deploy').toString()); success('Database is up to date.'); } (async () => { let err = false; - for (let fn of [checkEnv, checkConnection, checkTables, checkMigrations]) { + for (let fn of [checkEnv, checkConnection, checkDatabaseVersion, checkV1Tables, applyMigration]) { try { - await fn(); + fn.name === 'checkDatabaseVersion' ? await fn(databaseType) : await fn(); } catch (e) { - console.log(chalk.red(`✗ ${e.message}`)); + error(e.message); err = true; } finally { await prisma.$disconnect(); From 5bd86089185486ccbf94987857e5f9ed4cea902a Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Mon, 23 Jan 2023 10:06:52 -0800 Subject: [PATCH 2/2] fix checkDatabaseVersion message typo --- scripts/check-db.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check-db.js b/scripts/check-db.js index 87e22367..192536fe 100644 --- a/scripts/check-db.js +++ b/scripts/check-db.js @@ -57,7 +57,7 @@ async function checkDatabaseVersion(databaseType) { if (semver.lt(version, minVersion)) { throw new Error( - `Database version is not compatible. Please upgrade to ${databaseType} version to ${minVersion} or greater`, + `Database version is not compatible. Please upgrade ${databaseType} version to ${minVersion} or greater`, ); }