diff --git a/packages/core-database-postgres/CHANGELOG.md b/packages/core-database-postgres/CHANGELOG.md index 8348be784b..13db840f6b 100644 --- a/packages/core-database-postgres/CHANGELOG.md +++ b/packages/core-database-postgres/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased +## 0.2.11 - 2018-12-05 + +### Added + +- Store executed migrations in the database + ## 0.2.1 - 2018-12-05 ### Added diff --git a/packages/core-database-postgres/lib/connection.js b/packages/core-database-postgres/lib/connection.js index d20d86e4e1..f79ac58548 100644 --- a/packages/core-database-postgres/lib/connection.js +++ b/packages/core-database-postgres/lib/connection.js @@ -7,6 +7,7 @@ const crypto = require('crypto') const chunk = require('lodash/chunk') const pluralize = require('pluralize') const fs = require('fs') +const path = require('path') const { ConnectionInterface } = require('@arkecosystem/core-database') @@ -658,7 +659,21 @@ module.exports = class PostgresConnection extends ConnectionInterface { */ async __runMigrations() { for (const migration of migrations) { - await this.query.none(migration) + const { name } = path.parse(migration.file) + + if (name === '20180304100000-create-migrations-table') { + await this.query.none(migration) + } else { + const row = await this.db.migrations.findByName(name) + + if (row === null) { + logger.debug(`Migrating ${name}`) + + await this.query.none(migration) + + await this.db.migrations.create({ name }) + } + } } } diff --git a/packages/core-database-postgres/lib/migrations/20180304100000-create-migrations-table.sql b/packages/core-database-postgres/lib/migrations/20180304100000-create-migrations-table.sql new file mode 100644 index 0000000000..d1cc30448e --- /dev/null +++ b/packages/core-database-postgres/lib/migrations/20180304100000-create-migrations-table.sql @@ -0,0 +1,5 @@ +-- Table Definition +CREATE TABLE IF NOT EXISTS ${schema~}.migrations ( + "id" SERIAL PRIMARY KEY, + "name" VARCHAR(255) UNIQUE NOT NULL +); diff --git a/packages/core-database-postgres/lib/migrations/20180305300000-create-blocks-table.sql b/packages/core-database-postgres/lib/migrations/20180305300000-create-blocks-table.sql index 86c32105d6..58551aa6f2 100644 --- a/packages/core-database-postgres/lib/migrations/20180305300000-create-blocks-table.sql +++ b/packages/core-database-postgres/lib/migrations/20180305300000-create-blocks-table.sql @@ -14,6 +14,3 @@ CREATE TABLE IF NOT EXISTS ${schema~}.blocks ( "generator_public_key" VARCHAR(66) NOT NULL, "block_signature" VARCHAR(256) NOT NULL ); - --- Constraints -CREATE UNIQUE INDEX IF NOT EXISTS "blocks_unique" ON blocks ("height", "generator_public_key"); diff --git a/packages/core-database-postgres/lib/migrations/20181129400000-add-block_id-index-to-transactions-table.sql b/packages/core-database-postgres/lib/migrations/20181129400000-add-block_id-index-to-transactions-table.sql index 0300b968a1..7d2be3cc41 100644 --- a/packages/core-database-postgres/lib/migrations/20181129400000-add-block_id-index-to-transactions-table.sql +++ b/packages/core-database-postgres/lib/migrations/20181129400000-add-block_id-index-to-transactions-table.sql @@ -1,2 +1,2 @@ -- Constraints -CREATE INDEX IF NOT EXISTS "transactions_block_id" ON transactions ("block_id"); +CREATE INDEX IF NOT EXISTS "transactions_block_id" ON ${schema~}.transactions ("block_id"); diff --git a/packages/core-database-postgres/lib/migrations/20181204100000-blocks-generator_public_key-index.sql b/packages/core-database-postgres/lib/migrations/20181204100000-add-generator_public_key-index-to-blocks-table.sql similarity index 73% rename from packages/core-database-postgres/lib/migrations/20181204100000-blocks-generator_public_key-index.sql rename to packages/core-database-postgres/lib/migrations/20181204100000-add-generator_public_key-index-to-blocks-table.sql index 61e8e66469..c411dc74cb 100644 --- a/packages/core-database-postgres/lib/migrations/20181204100000-blocks-generator_public_key-index.sql +++ b/packages/core-database-postgres/lib/migrations/20181204100000-add-generator_public_key-index-to-blocks-table.sql @@ -1,2 +1,2 @@ -DROP INDEX "blocks_unique"; +DROP INDEX IF EXISTS "blocks_unique"; CREATE INDEX IF NOT EXISTS "blocks_generator_public_key" ON ${schema~}.blocks ("generator_public_key"); diff --git a/packages/core-database-postgres/lib/migrations/20181204200000-transactions-timestamp-index.sql b/packages/core-database-postgres/lib/migrations/20181204200000-add-transactions-timestamp-index-to-blocks-table.sql similarity index 100% rename from packages/core-database-postgres/lib/migrations/20181204200000-transactions-timestamp-index.sql rename to packages/core-database-postgres/lib/migrations/20181204200000-add-transactions-timestamp-index-to-blocks-table.sql diff --git a/packages/core-database-postgres/lib/migrations/20181204300000-transactions-sender-and-receiver-indexes.sql b/packages/core-database-postgres/lib/migrations/20181204300000-add-transactions-sender-and-receiver-indices-to-transactions-table.sql similarity index 100% rename from packages/core-database-postgres/lib/migrations/20181204300000-transactions-sender-and-receiver-indexes.sql rename to packages/core-database-postgres/lib/migrations/20181204300000-add-transactions-sender-and-receiver-indices-to-transactions-table.sql diff --git a/packages/core-database-postgres/lib/migrations/index.js b/packages/core-database-postgres/lib/migrations/index.js index 07f0d87fed..b3801097af 100644 --- a/packages/core-database-postgres/lib/migrations/index.js +++ b/packages/core-database-postgres/lib/migrations/index.js @@ -1,12 +1,25 @@ const { loadQueryFile } = require('../utils') module.exports = [ + loadQueryFile(__dirname, './20180304100000-create-migrations-table.sql'), loadQueryFile(__dirname, './20180305100000-create-wallets-table.sql'), loadQueryFile(__dirname, './20180305200000-create-rounds-table.sql'), loadQueryFile(__dirname, './20180305300000-create-blocks-table.sql'), loadQueryFile(__dirname, './20180305400000-create-transactions-table.sql'), - loadQueryFile(__dirname, './20181129400000-add-block_id-index-to-transactions-table.sql'), - loadQueryFile(__dirname, './20181204100000-blocks-generator_public_key-index.sql'), - loadQueryFile(__dirname, './20181204200000-transactions-timestamp-index.sql'), - loadQueryFile(__dirname, './20181204300000-transactions-sender-and-receiver-indexes.sql'), + loadQueryFile( + __dirname, + './20181129400000-add-block_id-index-to-transactions-table.sql', + ), + loadQueryFile( + __dirname, + './20181204100000-add-generator_public_key-index-to-blocks-table.sql', + ), + loadQueryFile( + __dirname, + './20181204200000-add-transactions-timestamp-index-to-blocks-table.sql', + ), + loadQueryFile( + __dirname, + './20181204300000-add-transactions-sender-and-receiver-indices-to-transactions-table.sql', + ), ] diff --git a/packages/core-database-postgres/lib/models/index.js b/packages/core-database-postgres/lib/models/index.js index b00c00cc7f..dfbbdc2b42 100644 --- a/packages/core-database-postgres/lib/models/index.js +++ b/packages/core-database-postgres/lib/models/index.js @@ -1,5 +1,6 @@ module.exports = { Block: require('./block'), + Migration: require('./migration'), Round: require('./round'), Transaction: require('./transaction'), Wallet: require('./wallet'), diff --git a/packages/core-database-postgres/lib/models/migration.js b/packages/core-database-postgres/lib/models/migration.js new file mode 100644 index 0000000000..f5f80cd506 --- /dev/null +++ b/packages/core-database-postgres/lib/models/migration.js @@ -0,0 +1,23 @@ +const Model = require('./model') + +module.exports = class Round extends Model { + /** + * The table associated with the model. + * @return {String} + */ + getTable() { + return 'migrations' + } + + /** + * The read-only structure with query-formatting columns. + * @return {Object} + */ + getColumnSet() { + return this.createColumnSet([ + { + name: 'name', + }, + ]) + } +} diff --git a/packages/core-database-postgres/lib/queries/index.js b/packages/core-database-postgres/lib/queries/index.js index 6a5b83cf1b..840e20000d 100644 --- a/packages/core-database-postgres/lib/queries/index.js +++ b/packages/core-database-postgres/lib/queries/index.js @@ -13,6 +13,10 @@ module.exports = { statistics: loadQueryFile(__dirname, './blocks/statistics.sql'), top: loadQueryFile(__dirname, './blocks/top.sql'), }, + migrations: { + create: loadQueryFile(__dirname, './migrations/create.sql'), + find: loadQueryFile(__dirname, './migrations/find.sql'), + }, rounds: { delete: loadQueryFile(__dirname, './rounds/delete.sql'), find: loadQueryFile(__dirname, './rounds/find.sql'), diff --git a/packages/core-database-postgres/lib/queries/migrations/create.sql b/packages/core-database-postgres/lib/queries/migrations/create.sql new file mode 100644 index 0000000000..c751058d0e --- /dev/null +++ b/packages/core-database-postgres/lib/queries/migrations/create.sql @@ -0,0 +1 @@ +INSERT INTO migrations (name) VALUES (${name}) diff --git a/packages/core-database-postgres/lib/queries/migrations/find.sql b/packages/core-database-postgres/lib/queries/migrations/find.sql new file mode 100644 index 0000000000..0828698f04 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/migrations/find.sql @@ -0,0 +1,3 @@ +SELECT * +FROM migrations +WHERE name = ${name} diff --git a/packages/core-database-postgres/lib/repositories/index.js b/packages/core-database-postgres/lib/repositories/index.js index 686c136090..59947e709d 100644 --- a/packages/core-database-postgres/lib/repositories/index.js +++ b/packages/core-database-postgres/lib/repositories/index.js @@ -1,5 +1,6 @@ module.exports = { blocks: require('./blocks'), + migrations: require('./migrations'), rounds: require('./rounds'), transactions: require('./transactions'), wallets: require('./wallets'), diff --git a/packages/core-database-postgres/lib/repositories/migrations.js b/packages/core-database-postgres/lib/repositories/migrations.js new file mode 100644 index 0000000000..a72275c6a7 --- /dev/null +++ b/packages/core-database-postgres/lib/repositories/migrations.js @@ -0,0 +1,22 @@ +const Repository = require('./repository') +const { Migration } = require('../models') +const { migrations: sql } = require('../queries') + +module.exports = class MigrationsRepository extends Repository { + /** + * Find a migration by its name. + * @param {String} name + * @return {Promise} + */ + async findByName(name) { + return this.db.oneOrNone(sql.find, { name }) + } + + /** + * Get the model related to this repository. + * @return {Object} + */ + getModel() { + return new Migration(this.pgp) + } +}