From a86b26a756d47629c73adfb0e142f0d3b476dc35 Mon Sep 17 00:00:00 2001 From: roschaefer Date: Mon, 20 Jan 2020 15:22:51 +0100 Subject: [PATCH] Various fixes for data migrations * Add unique index for `Migration`s * Fix proper use of `next` callback. First argument is potential error. * Update migration template --- backend/package.json | 8 +++--- backend/src/db/migrate/store.js | 28 +++++++++++-------- backend/src/db/migrate/template.js | 28 +++++++++++++++++-- ...387929122-merge_duplicate_user_accounts.js | 6 ++-- backend/src/models/Migration.js | 5 ++++ backend/src/models/index.js | 1 + 6 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 backend/src/models/Migration.js diff --git a/backend/package.json b/backend/package.json index 3c9fda287..b87091a1b 100644 --- a/backend/package.json +++ b/backend/package.json @@ -4,8 +4,10 @@ "description": "GraphQL Backend for Human Connection", "main": "src/index.js", "scripts": { - "build": "babel src/ -d dist/ --copy-files", + "__migrate": "migrate --compiler 'js:@babel/register' --migrations-dir ./src/db/migrations", + "prod:migrate": "migrate --migrations-dir ./dist/db/migrations --store ./dist/db/migrate/store.js", "start": "node dist/", + "build": "babel src/ -d dist/ --copy-files", "dev": "nodemon --exec babel-node src/ -e js,gql", "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/ -e js,gql", "lint": "eslint src --config .eslintrc.js", @@ -13,10 +15,8 @@ "db:clean": "babel-node src/db/clean.js", "db:reset": "yarn run db:clean", "db:seed": "babel-node src/db/seed.js", - "__migrate": "migrate --compiler 'js:@babel/register' --migrations-dir ./src/db/migrations", "db:migrate": "yarn run __migrate --store ./src/db/migrate/store.js", - "db:migrate:create": "yarn run __migrate --template-file ./src/db/migrate/template.js create", - "production:db:migrate": "migrate --migrations-dir ./dist/db/migrations --store ./dist/db/migrate/store.js" + "db:migrate:create": "yarn run __migrate --template-file ./src/db/migrate/template.js create" }, "author": "Human Connection gGmbH", "license": "MIT", diff --git a/backend/src/db/migrate/store.js b/backend/src/db/migrate/store.js index b2d65a0f2..97b057dac 100644 --- a/backend/src/db/migrate/store.js +++ b/backend/src/db/migrate/store.js @@ -1,32 +1,36 @@ import { getDriver, getNeode } from '../../db/neo4j' class Store { - async init(fn) { + async init(next) { const neode = getNeode() const { driver } = neode const session = driver.session() // eslint-disable-next-line no-console const writeTxResultPromise = session.writeTransaction(async txc => { await txc.run('CALL apoc.schema.assert({},{},true)') // drop all indices - return Promise.all([ - 'CALL db.index.fulltext.createNodeIndex("post_fulltext_search",["Post"],["title", "content"])', - 'CALL db.index.fulltext.createNodeIndex("user_fulltext_search",["User"],["name", "slug"])' - ].map(statement => txc.run(statement))) + return Promise.all( + [ + 'CALL db.index.fulltext.createNodeIndex("post_fulltext_search",["Post"],["title", "content"])', + 'CALL db.index.fulltext.createNodeIndex("user_fulltext_search",["User"],["name", "slug"])', + ].map(statement => txc.run(statement)), + ) }) try { await writeTxResultPromise await getNeode().schema.install() + // eslint-disable-next-line no-console console.log('Successfully created database indices and constraints!') + next() } catch (error) { console.log(error) // eslint-disable-line no-console + next(error, null) } finally { session.close() driver.close() - fn() } } - async load(fn) { + async load(next) { const driver = getDriver() const session = driver.session() const readTxResultPromise = session.readTransaction(async txc => { @@ -42,18 +46,19 @@ class Store { console.log( "No migrations found in database. If it's the first time you run migrations, then this is normal.", ) - return fn(null, {}) + return next(null, {}) } const [{ title: lastRun }] = migrations - fn(null, { lastRun, migrations }) + next(null, { lastRun, migrations }) } catch (error) { console.log(error) // eslint-disable-line no-console + next(error) } finally { session.close() } } - async save(set, fn) { + async save(set, next) { const driver = getDriver() const session = driver.session() const { migrations } = set @@ -70,11 +75,12 @@ class Store { }) try { await writeTxResultPromise + next() } catch (error) { console.log(error) // eslint-disable-line no-console + next(error) } finally { session.close() - fn() } } } diff --git a/backend/src/db/migrate/template.js b/backend/src/db/migrate/template.js index 941f2a9e3..b8511e9bb 100644 --- a/backend/src/db/migrate/template.js +++ b/backend/src/db/migrate/template.js @@ -1,7 +1,31 @@ +import { getDriver } from '../../db/neo4j' + +export const description = '' + export function up(next) { - next() + const driver = getDriver() + const session = driver.session() + try { + // Implement your migration here. + next() + } catch (err) { + next(err) + } finally { + session.close() + driver.close() + } } export function down(next) { - next() + const driver = getDriver() + const session = driver.session() + try { + // Rollback your migration here. + next() + } catch (err) { + next(err) + } finally { + session.close() + driver.close() + } } diff --git a/backend/src/db/migrations/1579387929122-merge_duplicate_user_accounts.js b/backend/src/db/migrations/1579387929122-merge_duplicate_user_accounts.js index 9dbc8ad05..ec38befc5 100644 --- a/backend/src/db/migrations/1579387929122-merge_duplicate_user_accounts.js +++ b/backend/src/db/migrations/1579387929122-merge_duplicate_user_accounts.js @@ -74,11 +74,11 @@ export function up(next) { next() }, error: error => { - throw new Error(error) + next(new Error(error), null) }, }) } -export function down() { - throw new Error('Irreversible migration') +export function down(next) { + next(new Error('Irreversible migration')) } diff --git a/backend/src/models/Migration.js b/backend/src/models/Migration.js new file mode 100644 index 000000000..e36d10ac3 --- /dev/null +++ b/backend/src/models/Migration.js @@ -0,0 +1,5 @@ +export default { + title: { type: 'string', primary: true, token: true }, + description: { type: 'string' }, + timestamp: { type: 'number', unique: true }, +} diff --git a/backend/src/models/index.js b/backend/src/models/index.js index 047ace67c..dbb6a927e 100644 --- a/backend/src/models/index.js +++ b/backend/src/models/index.js @@ -13,4 +13,5 @@ export default { Location: require('./Location.js').default, Donations: require('./Donations.js').default, Report: require('./Report.js').default, + Migration: require('./Migration.js').default, }