Add initial database migration
This commit is contained in:
parent
a57b86257c
commit
8dac92464d
6
.gitignore
vendored
6
.gitignore
vendored
@ -57,4 +57,8 @@ Temporary Items
|
|||||||
public/generated/*
|
public/generated/*
|
||||||
|
|
||||||
# Don't commit environment file
|
# Don't commit environment file
|
||||||
.env
|
.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",
|
"glob": "^6.0.4",
|
||||||
"helmet": "^1.1.0",
|
"helmet": "^1.1.0",
|
||||||
"highlight.js": "^9.1.0",
|
"highlight.js": "^9.1.0",
|
||||||
|
"knex": "^0.10.0",
|
||||||
"lodash": "^4.5.0",
|
"lodash": "^4.5.0",
|
||||||
"marked": "^0.3.5",
|
"marked": "^0.3.5",
|
||||||
"morgan": "~1.6.1",
|
"morgan": "~1.6.1",
|
||||||
"nodemon": "^1.9.0",
|
"nodemon": "^1.9.0",
|
||||||
|
"scrypt": "^6.0.1",
|
||||||
|
"sqlite3": "^3.1.1",
|
||||||
"winston": "^2.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": {
|
"devDependencies": {
|
||||||
"chai": "^3.4.1",
|
"chai": "^3.4.1",
|
||||||
"chai-as-promised": "^5.2.0",
|
"chai-as-promised": "^5.2.0",
|
||||||
@ -42,9 +45,6 @@
|
|||||||
"pre-commit": "^1.1.2",
|
"pre-commit": "^1.1.2",
|
||||||
"supertest": "^1.1.0"
|
"supertest": "^1.1.0"
|
||||||
},
|
},
|
||||||
"directories": {
|
|
||||||
"lib": "./lib"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">4.0.0"
|
"node": ">4.0.0"
|
||||||
},
|
},
|
||||||
@ -63,7 +63,7 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/timw4mail/crispy-train.git"
|
"url": "https://git.timshomepage.net/timw4mail/ProgBlog.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "nodemon server.js",
|
"start": "nodemon server.js",
|
||||||
|
Reference in New Issue
Block a user