Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data & Fixture Migrations v005 #6628

Merged
merged 8 commits into from
Apr 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions core/server/data/migration/005/01-drop-hidden-column-from-tags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
var commands = require('../../schema').commands,
db = require('../../db'),

table = 'tags',
column = 'hidden',
message = 'Removing column: ' + table + '.' + column;

module.exports = function dropHiddenColumnFromTags(logger) {
return db.knex.schema.hasTable(table).then(function (exists) {
if (exists) {
return db.knex.schema.hasColumn(table, column).then(function (exists) {
if (exists) {
logger.info(message);
return commands.dropColumn(table, column);
} else {
logger.warn(message);
}
});
} else {
// @TODO: this should probably be an error
logger.warn(message);
}
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
db = require('../../db'),

tables = ['posts', 'tags', 'users'],
column = 'visibility';

module.exports = function addVisibilityColumnToKeyTables(logger) {
return Promise.mapSeries(tables, function (table) {
var message = 'Adding column: ' + table + '.' + column;
return db.knex.schema.hasTable(table).then(function (exists) {
if (exists) {
return db.knex.schema.hasColumn(table, column).then(function (exists) {
if (!exists) {
logger.info(message);
return commands.addColumn(table, column);
} else {
logger.warn(message);
}
});
} else {
// @TODO: this should probably be an error
logger.warn(message);
}
});
});
};
24 changes: 24 additions & 0 deletions core/server/data/migration/005/03-add-mobiledoc-column-to-posts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
var commands = require('../../schema').commands,
db = require('../../db'),

table = 'posts',
column = 'mobiledoc',
message = 'Adding column: ' + table + '.' + column;

module.exports = function addMobiledocColumnToPosts(logger) {
return db.knex.schema.hasTable(table).then(function (exists) {
if (exists) {
return db.knex.schema.hasColumn(table, column).then(function (exists) {
if (!exists) {
logger.info(message);
return commands.addColumn(table, column);
} else {
logger.warn(message);
}
});
} else {
// @TODO: this should probably be an error
logger.warn(message);
}
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
db = require('../../db'),

table = 'users',
columns = ['facebook', 'twitter'];

module.exports = function addSocialMediaColumnsToUsers(logger) {
return db.knex.schema.hasTable(table).then(function (exists) {
if (exists) {
return Promise.mapSeries(columns, function (column) {
var message = 'Adding column: ' + table + '.' + column;
return db.knex.schema.hasColumn(table, column).then(function (exists) {
if (!exists) {
logger.info(message);
return commands.addColumn(table, column);
} else {
logger.warn(message);
}
});
});
} else {
// @TODO: this should probably be an error
logger.warn('Adding columns to table: ' + table);
}
});
};
11 changes: 11 additions & 0 deletions core/server/data/migration/005/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = [
// Drop hidden column from tags table
require('./01-drop-hidden-column-from-tags'),
// Add visibility column to posts, tags, and users tables
require('./02-add-visibility-column-to-key-tables'),
// Add mobiledoc column to posts
require('./03-add-mobiledoc-column-to-posts'),
// Add social media columns to isers
require('./04-add-social-media-columns-to-users')

];
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Update the `ghost-*` clients so that they definitely have a proper secret
var models = require('../../../../models'),
_ = require('lodash'),
Promise = require('bluebird'),
crypto = require('crypto'),

message = 'Updating client secret';

module.exports = function updateGhostClientsSecrets(options, logger) {
return models.Clients.forge().query('where', 'secret', '=', 'not_available').fetch().then(function (results) {
if (results.models.length === 0) {
logger.warn(message);
return;
}

return Promise.map(results.models, function mapper(client) {
logger.info(message + ' (' + client.slug + ')');
client.secret = crypto.randomBytes(6).toString('hex');

return models.Client.edit(
_.extend({}, client, {secret: crypto.randomBytes(6).toString('hex')},
_.extend({}, options, {id: client.id}))
);
});
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Create a new `ghost-scheduler` client for use in themes
var models = require('../../../../models'),

schedulerClient = require('../utils').findModelFixtureEntry('Client', {slug: 'ghost-scheduler'}),
message = 'Add ghost-scheduler client fixture';

module.exports = function addGhostFrontendClient(options, logger) {
return models.Client.findOne({slug: schedulerClient.slug}).then(function (client) {
if (!client) {
logger.info(message);
return models.Client.add(schedulerClient, options);
} else {
logger.warn(message);
}
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Update the permissions & permissions_roles tables to get the new entries
var utils = require('../utils');

function getClientPermissions() {
return utils.findModelFixtures('Permission', {object_type: 'client'});
}

function getClientRelations() {
return utils.findPermissionRelationsForObject('client');
}

function printResult(logger, result, message) {
if (result.done === result.expected) {
logger.info(message);
} else {
logger.warn('(' + result.done + '/' + result.expected + ') ' + message);
}
}

module.exports = function addClientPermissions(options, logger) {
var modelToAdd = getClientPermissions(),
relationToAdd = getClientRelations();

return utils.addFixturesForModel(modelToAdd).then(function (result) {
printResult(logger, result, 'Adding permissions fixtures for clients');
return utils.addFixturesForRelation(relationToAdd);
}).then(function (result) {
printResult(logger, result, 'Adding permissions_roles fixtures for clients');
});
};
8 changes: 8 additions & 0 deletions core/server/data/migration/fixtures/005/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = [
// add jquery setting and privacy info
require('./01-update-ghost-client-secrets'),
// add ghost-scheduler client
require('./02-add-ghost-scheduler-client'),
// add client permissions and permission_role relations
require('./03-add-client-permissions')
];
40 changes: 37 additions & 3 deletions core/server/data/migration/fixtures/fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@
"name": "Ghost Frontend",
"slug": "ghost-frontend",
"status": "enabled"
},
{
"name": "Ghost Scheduler",
"slug": "ghost-scheduler",
"status": "enabled",
"type": "web"
}
]
},
Expand Down Expand Up @@ -218,6 +224,31 @@
"name": "Browse roles",
"action_type": "browse",
"object_type": "role"
},
{
"name": "Browse clients",
"action_type": "browse",
"object_type": "client"
},
{
"name": "Read clients",
"action_type": "read",
"object_type": "client"
},
{
"name": "Edit clients",
"action_type": "edit",
"object_type": "client"
},
{
"name": "Add clients",
"action_type": "add",
"object_type": "client"
},
{
"name": "Delete clients",
"action_type": "destroy",
"object_type": "client"
}
]
}
Expand Down Expand Up @@ -245,23 +276,26 @@
"tag": "all",
"theme": "all",
"user": "all",
"role": "all"
"role": "all",
"client": "all"
},
"Editor": {
"post": "all",
"setting": ["browse", "read"],
"slug": "all",
"tag": "all",
"user": "all",
"role": "all"
"role": "all",
"client": "all"
},
"Author": {
"post": ["browse", "read", "add"],
"setting": ["browse", "read"],
"slug": "all",
"tag": ["browse", "read", "add"],
"user": ["browse", "read"],
"role": ["browse"]
"role": ["browse"],
"client": "all"
}
}
},
Expand Down
24 changes: 3 additions & 21 deletions core/server/data/migration/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
var Promise = require('bluebird'),
crypto = require('crypto'),
versioning = require('../schema').versioning,
var versioning = require('../schema').versioning,
errors = require('../../errors'),
models = require('../../models'),

// private
logger,
fixClientSecret,
populate = require('./populate'),
update = require('./update'),

Expand All @@ -28,21 +24,8 @@ logger = {
}
};

// TODO: move to migration.to005() for next DB version
fixClientSecret = function () {
return models.Clients.forge().query('where', 'secret', '=', 'not_available').fetch().then(function updateClients(results) {
return Promise.map(results.models, function mapper(client) {
if (process.env.NODE_ENV.indexOf('testing') !== 0) {
logger.info('Updating client secret');
client.secret = crypto.randomBytes(6).toString('hex');
}
return models.Client.edit(client, {context: {internal: true}, id: client.id});
});
});
};

// Check for whether data is needed to be bootstrapped or not
init = function (tablesOnly) {
init = function init(tablesOnly) {
tablesOnly = tablesOnly || false;

// There are 4 possibilities:
Expand All @@ -63,8 +46,7 @@ init = function (tablesOnly) {
// 1. The database exists and is up-to-date
} else if (databaseVersion === defaultVersion) {
logger.info('Up-to-date at version ' + databaseVersion);
// TODO: temporary fix for missing client.secret
return fixClientSecret();
return;

// 3. The database exists but the currentVersion setting does not or cannot be understood
} else {
Expand Down
2 changes: 1 addition & 1 deletion core/server/data/schema/default-settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"core": {
"databaseVersion": {
"defaultValue": "004"
"defaultValue": "005"
},
"dbHash": {
"defaultValue": null
Expand Down
9 changes: 7 additions & 2 deletions core/server/data/schema/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ module.exports = {
title: {type: 'string', maxlength: 150, nullable: false},
slug: {type: 'string', maxlength: 150, nullable: false, unique: true},
markdown: {type: 'text', maxlength: 16777215, fieldtype: 'medium', nullable: true},
mobiledoc: {type: 'text', maxlength: 1000000000, fieldtype: 'long', nullable: true},
html: {type: 'text', maxlength: 16777215, fieldtype: 'medium', nullable: true},
image: {type: 'text', maxlength: 2000, nullable: true},
featured: {type: 'bool', nullable: false, defaultTo: false, validations: {isIn: [[0, 1, false, true]]}},
page: {type: 'bool', nullable: false, defaultTo: false, validations: {isIn: [[0, 1, false, true]]}},
status: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'draft'},
language: {type: 'string', maxlength: 6, nullable: false, defaultTo: 'en_US'},
visibility: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'public', validations: {isIn: [['public']]}},
meta_title: {type: 'string', maxlength: 150, nullable: true},
meta_description: {type: 'string', maxlength: 200, nullable: true},
author_id: {type: 'integer', nullable: false},
Expand All @@ -33,9 +35,12 @@ module.exports = {
bio: {type: 'string', maxlength: 200, nullable: true},
website: {type: 'text', maxlength: 2000, nullable: true, validations: {isEmptyOrURL: true}},
location: {type: 'text', maxlength: 65535, nullable: true},
facebook: {type: 'text', maxlength: 2000, nullable: true, validations: {isEmptyOrURL: true}},
twitter: {type: 'text', maxlength: 2000, nullable: true, validations: {isEmptyOrURL: true}},
accessibility: {type: 'text', maxlength: 65535, nullable: true},
status: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'active'},
language: {type: 'string', maxlength: 6, nullable: false, defaultTo: 'en_US'},
visibility: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'public', validations: {isIn: [['public']]}},
meta_title: {type: 'string', maxlength: 150, nullable: true},
meta_description: {type: 'string', maxlength: 200, nullable: true},
tour: {type: 'text', maxlength: 65535, nullable: true},
Expand Down Expand Up @@ -105,8 +110,8 @@ module.exports = {
slug: {type: 'string', maxlength: 150, nullable: false, unique: true},
description: {type: 'string', maxlength: 200, nullable: true},
image: {type: 'text', maxlength: 2000, nullable: true},
hidden: {type: 'bool', nullable: false, defaultTo: false, validations: {isIn: [[0, 1, false, true]]}},
parent_id: {type: 'integer', nullable: true},
visibility: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'public', validations: {isIn: [['public', 'internal']]}},
meta_title: {type: 'string', maxlength: 150, nullable: true},
meta_description: {type: 'string', maxlength: 200, nullable: true},
created_at: {type: 'dateTime', nullable: false},
Expand Down Expand Up @@ -167,7 +172,7 @@ module.exports = {
redirection_uri: {type: 'string', maxlength: 2000, nullable: true},
logo: {type: 'string', maxlength: 2000, nullable: true},
status: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'development'},
type: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'ua'},
type: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'ua', validations: {isIn: [['ua', 'web', 'native']]}},
description: {type: 'string', maxlength: 200, nullable: true},
created_at: {type: 'dateTime', nullable: false},
created_by: {type: 'integer', nullable: false},
Expand Down