Add initial database migration
This commit is contained in:
parent
a57b86257c
commit
8dac92464d
4
.gitignore
vendored
4
.gitignore
vendored
@ -58,3 +58,7 @@ public/generated/*
|
||||
|
||||
# Don't commit environment file
|
||||
.env
|
||||
|
||||
# Don't commit database migration config file or dev database
|
||||
knexfile.js
|
||||
dev.sqlite3
|
54
app/migration_helpers.js
Normal file
54
app/migration_helpers.js
Normal file
@ -0,0 +1,54 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Migration helper methods
|
||||
* @type {Object}
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
get_db_type(knex) {
|
||||
switch(knex.client.config.client) {
|
||||
case 'postgresql':
|
||||
case 'postgres':
|
||||
case 'pg':
|
||||
return 'pg';
|
||||
|
||||
default:
|
||||
return knex.client.config.client;
|
||||
}
|
||||
},
|
||||
|
||||
pg_timestamp_update_function () {
|
||||
return `CREATE OR REPLACE FUNCTION progblog_update_modified_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = now();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';`;
|
||||
},
|
||||
|
||||
pg_create_timestamp_update_trigger(table) {
|
||||
return `CREATE TRIGGER update_${table}_modtime
|
||||
BEFORE UPDATE ON "${table}"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE progblog_update_modified_column();`;
|
||||
},
|
||||
|
||||
pg_delete_timestamp_update_trigger(table) {
|
||||
return `DROP TRIGGER IF EXISTS update_${table}_modtime ON "${table}";`;
|
||||
},
|
||||
|
||||
sqlite3_create_timestamp_update_trigger(table) {
|
||||
return `CREATE TRIGGER IF NOT EXISTS [UpdateModified]
|
||||
BEFORE UPDATE ON "${table}"
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE "${table}" SET updated_at = CURRENT_TIMESTAMP WHERE id = old.id;
|
||||
END`;
|
||||
},
|
||||
|
||||
sqlite3_delete_timestamp_update_trigger() {
|
||||
return `DROP TRIGGER IF EXISTS [UpdateModified]`;
|
||||
}
|
||||
};
|
74
migrations/20160224105517_initial.js
Normal file
74
migrations/20160224105517_initial.js
Normal file
@ -0,0 +1,74 @@
|
||||
'use strict';
|
||||
|
||||
const helpers = require('../app/migration_helpers');
|
||||
|
||||
exports.up = function(knex, Promise) {
|
||||
const dbType = helpers.get_db_type(knex);
|
||||
|
||||
// Defer has the promise resulting from creating the initial tables
|
||||
let defer = knex.schema.createTableIfNotExists('users', (table) => {
|
||||
table.comment('User authentication table');
|
||||
table.increments()
|
||||
.unsigned();
|
||||
table.string('user');
|
||||
table.binary('password_hash');
|
||||
table.timestamp('created_at')
|
||||
.defaultTo(knex.fn.now());
|
||||
table.timestamp('updated_at')
|
||||
.defaultTo(knex.fn.now());
|
||||
}).then(() => {
|
||||
return knex.schema.createTableIfNotExists('posts', (table) => {
|
||||
table.comment('Blog post table');
|
||||
table.increments()
|
||||
.unsigned();
|
||||
table.integer('created_by')
|
||||
.unsigned()
|
||||
.references('users.id');
|
||||
table.string('uri')
|
||||
.index()
|
||||
.comment('The uri segment of the blog post');
|
||||
table.string('title')
|
||||
.comment('The title of the blog post');
|
||||
table.text('content')
|
||||
.comment('The content of the blog post');
|
||||
table.timestamp('created_at')
|
||||
.defaultTo(knex.fn.now());
|
||||
table.timestamp('updated_at')
|
||||
.defaultTo(knex.fn.now());
|
||||
});
|
||||
});
|
||||
|
||||
if ('pg' === dbType) {
|
||||
// Create the function to update
|
||||
return knex.schema.raw(helpers.pg_timestamp_update_function())
|
||||
// Create the tables
|
||||
.then(() => defer)
|
||||
|
||||
// Add trigger for tables
|
||||
.then(() => knex.schema.raw(helpers.pg_create_timestamp_update_trigger('users')))
|
||||
.then(() => knex.schema.raw(helpers.pg_create_timestamp_update_trigger('posts')));
|
||||
} else if ('sqlite3' === dbType) {
|
||||
return defer.then(() => knex.schema.raw(helpers.sqlite3_create_timestamp_update_trigger('users')))
|
||||
.then(() => knex.schema.raw(helpers.sqlite3_create_timestamp_update_trigger('posts')));
|
||||
} else {
|
||||
return defer;
|
||||
}
|
||||
};
|
||||
|
||||
exports.down = function(knex, Promise) {
|
||||
const dbType = helpers.get_db_type(knex);
|
||||
let defer = knex.schema.dropTableIfExists('posts')
|
||||
.then(() => knex.schema.dropTableIfExists('users'));
|
||||
|
||||
if ('pg' === dbType) {
|
||||
return knex.schema.raw(helpers.pg_delete_timestamp_update_trigger('users'))
|
||||
.then(() => knex.schema.raw(helpers.pg_delete_timestamp_update_trigger('posts')))
|
||||
.then(() => defer);
|
||||
} else if ('sqlite3' === dbType) {
|
||||
return knex.schema.raw(helpers.sqlite3_delete_timestamp_update_trigger('users'))
|
||||
.then(() => knex.schema.raw(helpers.sqlite3_delete_timestamp_update_trigger('posts')))
|
||||
.then(() => defer);
|
||||
} else {
|
||||
return defer;
|
||||
}
|
||||
};
|
10
package.json
10
package.json
@ -17,13 +17,16 @@
|
||||
"glob": "^6.0.4",
|
||||
"helmet": "^1.1.0",
|
||||
"highlight.js": "^9.1.0",
|
||||
"knex": "^0.10.0",
|
||||
"lodash": "^4.5.0",
|
||||
"marked": "^0.3.5",
|
||||
"morgan": "~1.6.1",
|
||||
"nodemon": "^1.9.0",
|
||||
"scrypt": "^6.0.1",
|
||||
"sqlite3": "^3.1.1",
|
||||
"winston": "^2.1.1"
|
||||
},
|
||||
"description": "An Opinionated Take on express with use of ES6 features",
|
||||
"description": "A simple blog with built-in code snippet functionality",
|
||||
"devDependencies": {
|
||||
"chai": "^3.4.1",
|
||||
"chai-as-promised": "^5.2.0",
|
||||
@ -42,9 +45,6 @@
|
||||
"pre-commit": "^1.1.2",
|
||||
"supertest": "^1.1.0"
|
||||
},
|
||||
"directories": {
|
||||
"lib": "./lib"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">4.0.0"
|
||||
},
|
||||
@ -63,7 +63,7 @@
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/timw4mail/crispy-train.git"
|
||||
"url": "https://git.timshomepage.net/timw4mail/ProgBlog.git"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "nodemon server.js",
|
||||
|
Reference in New Issue
Block a user