diff --git a/keyserver/src/database/db-version.js b/keyserver/src/database/db-version.js new file mode 100644 index 000000000..0328a12b9 --- /dev/null +++ b/keyserver/src/database/db-version.js @@ -0,0 +1,31 @@ +// @flow + +import type { QueryResults } from 'mysql'; + +import { dbQuery, SQL } from './database'; + +async function fetchDBVersion(): Promise { + const versionQuery = SQL` + SELECT data + FROM metadata + WHERE name = 'db_version'; + `; + const [[versionResult]] = await dbQuery(versionQuery); + if (!versionResult) { + return -1; + } + return versionResult.data; +} + +async function updateDBVersion(dbVersion: number): Promise { + const updateQuery = SQL` + INSERT INTO metadata (name, data) + VALUES ('db_version', ${dbVersion}) + ON DUPLICATE KEY + UPDATE + data = ${dbVersion}; + `; + return dbQuery(updateQuery); +} + +export { fetchDBVersion, updateDBVersion }; diff --git a/keyserver/src/database/migrations.js b/keyserver/src/database/migrations.js index d41e8e9ae..a83c5edd5 100644 --- a/keyserver/src/database/migrations.js +++ b/keyserver/src/database/migrations.js @@ -1,101 +1,78 @@ // @flow import type { QueryResults } from 'mysql'; import { getMessageForException } from 'lib/utils/errors'; import { dbQuery, SQL } from './database'; +import { fetchDBVersion, updateDBVersion } from './db-version'; import { migrations } from './migration-config'; import { setupDB } from './setup-db'; async function migrate(): Promise { let dbVersion = null; try { dbVersion = await setUpDBAndReturnVersion(); console.log(`(node:${process.pid}) DB version: ${dbVersion}`); } catch (e) { const dbVersionExceptionMessage = String(getMessageForException(e)); console.error(`(node:${process.pid}) ${dbVersionExceptionMessage}`); return false; } for (const [idx, migration] of migrations.entries()) { if (idx <= dbVersion) { continue; } try { await startTransaction(); await migration(); await updateDBVersion(idx); await commitTransaction(); console.log(`(node:${process.pid}) migration ${idx} succeeded.`); } catch (e) { const transactionExceptionMessage = String(getMessageForException(e)); console.error(`(node:${process.pid}) migration ${idx} failed.`); console.error(transactionExceptionMessage); await rollbackTransaction(); return false; } } return true; } async function setUpDBAndReturnVersion(): Promise { try { return await fetchDBVersion(); } catch (e) { if (e.errno !== 1146) { throw e; } await setupDB(); return await fetchDBVersion(); } } -async function fetchDBVersion(): Promise { - const versionQuery = SQL` - SELECT data - FROM metadata - WHERE name = 'db_version'; - `; - const [[versionResult]] = await dbQuery(versionQuery); - if (!versionResult) { - return -1; - } - return versionResult.data; -} - -async function updateDBVersion(dbVersion: number): Promise { - const updateQuery = SQL` - INSERT INTO metadata (name, data) - VALUES ('db_version', ${dbVersion}) - ON DUPLICATE KEY - UPDATE - data = ${dbVersion}; - `; - return dbQuery(updateQuery); -} - async function startTransaction(): Promise { const beginTxnQuery = SQL` START TRANSACTION; `; return dbQuery(beginTxnQuery); } async function commitTransaction(): Promise { const endTxnQuery = SQL` COMMIT; `; return dbQuery(endTxnQuery); } async function rollbackTransaction(): Promise { const rollbackTxnQuery = SQL` ROLLBACK; `; return dbQuery(rollbackTxnQuery); } export { migrate };