0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-01 02:41:39 -05:00

🔥 remove all migration files (#7498)

refs #7489
- a simple PR to remove all the old migration files
- remove related tests
This commit is contained in:
Katharina Irrgang 2016-10-05 20:57:32 +02:00 committed by Hannah Wolfe
parent bb07096b9d
commit 32700a0e5a
39 changed files with 0 additions and 3847 deletions

View file

@ -1,26 +0,0 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
table = 'users',
column = 'tour',
message = 'Adding column: ' + table + '.' + column;
module.exports = function addTourColumnToUsers(options, logger) {
var transaction = options.transacting;
return transaction.schema.hasTable(table)
.then(function (exists) {
if (!exists) {
return Promise.reject(new Error('Table does not exist!'));
}
return transaction.schema.hasColumn(table, column);
})
.then(function (exists) {
if (!exists) {
logger.info(message);
return commands.addColumn(table, column, transaction);
} else {
logger.warn(message);
}
});
};

View file

@ -1,26 +0,0 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
table = 'posts_tags',
column = 'sort_order',
message = 'Adding column: ' + table + '.' + column;
module.exports = function addSortOrderColumnToPostsTags(options, logger) {
var transaction = options.transacting;
return transaction.schema.hasTable(table)
.then(function (exists) {
if (!exists) {
return Promise.reject(new Error('Table does not exist!'));
}
return transaction.schema.hasColumn(table, column);
})
.then(function (exists) {
if (!exists) {
logger.info(message);
return commands.addColumn(table, column, transaction);
} else {
logger.warn(message);
}
});
};

View file

@ -1,29 +0,0 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
table = 'clients',
columns = ['redirection_uri', 'logo', 'status', 'type', 'description'];
module.exports = function addManyColumnsToClients(options, logger) {
var transaction = options.transacting;
return transaction.schema.hasTable(table)
.then(function (exists) {
if (!exists) {
return Promise.reject(new Error('Table does not exist!'));
}
return Promise.mapSeries(columns, function (column) {
var message = 'Adding column: ' + table + '.' + column;
return transaction.schema.hasColumn(table, column)
.then(function (exists) {
if (!exists) {
logger.info(message);
return commands.addColumn(table, column, transaction);
} else {
logger.warn(message);
}
});
});
});
};

View file

@ -1,17 +0,0 @@
var commands = require('../../schema').commands,
table = 'client_trusted_domains',
message = 'Creating table: ' + table;
module.exports = function addClientTrustedDomainsTable(options, logger) {
var transaction = options.transacting;
return transaction.schema.hasTable(table)
.then(function (exists) {
if (!exists) {
logger.info(message);
return commands.createTable(table, transaction);
} else {
logger.warn(message);
}
});
};

View file

@ -1,26 +0,0 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
table = 'clients',
column = 'secret',
message = 'Dropping unique on: ' + table + '.' + column;
module.exports = function dropUniqueOnClientsSecret(options, logger) {
var transaction = options.transacting;
return transaction.schema.hasTable(table)
.then(function (exists) {
if (!exists) {
return Promise.reject(new Error('Table does not exist!'));
}
return commands.getIndexes(table, transaction);
})
.then(function (indexes) {
if (indexes.indexOf(table + '_' + column + '_unique') > -1) {
logger.info(message);
return commands.dropUnique(table, column, transaction);
} else {
logger.warn(message);
}
});
};

View file

@ -1,12 +0,0 @@
module.exports = [
// Added tour column to users
require('./01-add-tour-column-to-users'),
// Added sort_order to posts_tags
require('./02-add-sortorder-column-to-poststags'),
// Added redirection_uri, logo, status, type & description columns to clients
require('./03-add-many-columns-to-clients'),
// Added client_trusted_domains table
require('./04-add-clienttrusteddomains-table'),
// Dropped unique index on client secret
require('./05-drop-unique-on-clients-secret')
];

View file

@ -1,26 +0,0 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
table = 'tags',
column = 'hidden',
message = 'Removing column: ' + table + '.' + column;
module.exports = function dropHiddenColumnFromTags(options, logger) {
var transaction = options.transacting;
return transaction.schema.hasTable(table)
.then(function (exists) {
if (!exists) {
return Promise.reject(new Error('Table does not exist!'));
}
return transaction.schema.hasColumn(table, column);
})
.then(function (exists) {
if (exists) {
logger.info(message);
return commands.dropColumn(table, column, transaction);
} else {
logger.warn(message);
}
});
};

View file

@ -1,29 +0,0 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
tables = ['posts', 'tags', 'users'],
column = 'visibility';
module.exports = function addVisibilityColumnToKeyTables(options, logger) {
var transaction = options.transacting;
return Promise.mapSeries(tables, function (table) {
var message = 'Adding column: ' + table + '.' + column;
return transaction.schema.hasTable(table)
.then(function (exists) {
if (!exists) {
return Promise.reject(new Error('Table does not exist!'));
}
return transaction.schema.hasColumn(table, column);
})
.then(function (exists) {
if (!exists) {
logger.info(message);
return commands.addColumn(table, column, transaction);
} else {
logger.warn(message);
}
});
});
};

View file

@ -1,26 +0,0 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
table = 'posts',
column = 'mobiledoc',
message = 'Adding column: ' + table + '.' + column;
module.exports = function addMobiledocColumnToPosts(options, logger) {
var transaction = options.transacting;
return transaction.schema.hasTable(table)
.then(function (exists) {
if (!exists) {
return Promise.reject(new Error('Table does not exist!'));
}
return transaction.schema.hasColumn(table, column);
})
.then(function (exists) {
if (!exists) {
logger.info(message);
return commands.addColumn(table, column, transaction);
} else {
logger.warn(message);
}
});
};

View file

@ -1,28 +0,0 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
table = 'users',
columns = ['facebook', 'twitter'];
module.exports = function addSocialMediaColumnsToUsers(options, logger) {
var transaction = options.transacting;
return transaction.schema.hasTable(table)
.then(function (exists) {
if (!exists) {
return Promise.reject(new Error('Table does not exist!'));
}
return Promise.mapSeries(columns, function (column) {
var message = 'Adding column: ' + table + '.' + column;
return transaction.schema.hasColumn(table, column).then(function (exists) {
if (!exists) {
logger.info(message);
return commands.addColumn(table, column, transaction);
} else {
logger.warn(message);
}
});
});
});
};

View file

@ -1,16 +0,0 @@
var commands = require('../../schema').commands,
table = 'subscribers',
message = 'Creating table: ' + table;
module.exports = function addSubscribersTable(options, logger) {
var transaction = options.transacting;
return transaction.schema.hasTable(table).then(function (exists) {
if (!exists) {
logger.info(message);
return commands.createTable(table, transaction);
} else {
logger.warn(message);
}
});
};

View file

@ -1,12 +0,0 @@
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 users
require('./04-add-social-media-columns-to-users'),
// Add subscribers table
require('./05-add-subscribers-table')
];

View file

@ -1 +0,0 @@
module.exports = [];

View file

@ -1,26 +0,0 @@
var Promise = require('bluebird'),
commands = require('../../schema').commands,
table = 'posts',
column = 'amp',
message = 'Adding column: ' + table + '.' + column;
module.exports = function addAmpColumnToPosts(options, logger) {
var transaction = options.transacting;
return transaction.schema.hasTable(table)
.then(function (exists) {
if (!exists) {
return Promise.reject(new Error('Table does not exist!'));
}
return transaction.schema.hasColumn(table, column);
})
.then(function (exists) {
if (!exists) {
logger.info(message);
return commands.addColumn(table, column, transaction);
} else {
logger.warn(message);
}
});
};

View file

@ -1,4 +0,0 @@
module.exports = [
// Add amp column to posts
require('./01-add-amp-column-to-posts')
];

View file

@ -1,57 +0,0 @@
// Moves jQuery inclusion to code injection via ghost_foot
var _ = require('lodash'),
Promise = require('bluebird'),
serverPath = '../../../../',
config = require(serverPath + 'config'),
models = require(serverPath + 'models'),
notifications = require(serverPath + 'api/notifications'),
i18n = require(serverPath + 'i18n'),
// These messages are shown in the admin UI, not the console, and should therefore be translated
jquery = [
i18n.t('notices.data.fixtures.canSafelyDelete'),
'<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>\n\n'
],
privacyMessage = [
i18n.t('notices.data.fixtures.jQueryRemoved'),
i18n.t('notices.data.fixtures.canBeChanged')
],
message = 'Adding jQuery link to ghost_foot';
module.exports = function moveJQuery(options, logger) {
var value;
return models.Settings.findOne('ghost_foot', options)
.then(function (setting) {
if (setting) {
value = setting.get('value');
// Only add jQuery if it's not already in there
if (value.indexOf(jquery.join('')) === -1) {
logger.info(message);
value = jquery.join('') + value;
return models.Settings.edit({key: 'ghost_foot', value: value}, options);
} else {
logger.warn(message);
}
} else {
logger.warn(message);
}
})
.then(function () {
if (_.isEmpty(config.get('privacy'))) {
return Promise.resolve();
}
logger.info(privacyMessage.join(' ').replace(/<\/?strong>/g, ''));
return notifications.add({
notifications: [{
type: 'info',
message: privacyMessage.join(' ')
}]
}, options);
});
};

View file

@ -1,15 +0,0 @@
// Update the `isPrivate` setting, so that it has a type of `private` rather than `blog`
var models = require('../../../../models'),
message = 'Update isPrivate setting';
module.exports = function updatePrivateSetting(options, logger) {
return models.Settings.findOne('isPrivate', options).then(function (setting) {
if (setting && setting.get('type') !== 'private') {
logger.info(message);
return models.Settings.edit({key: 'isPrivate', type: 'private'}, options);
} else {
logger.warn(message);
}
});
};

View file

@ -1,14 +0,0 @@
// Update the `password` setting, so that it has a type of `private` rather than `blog`
var models = require('../../../../models'),
message = 'Update password setting';
module.exports = function updatePasswordSetting(options, logger) {
return models.Settings.findOne('password', options).then(function (setting) {
if (setting && setting.get('type') !== 'private') {
logger.info(message);
return models.Settings.edit({key: 'password', type: 'private'}, options);
} else {
logger.warn(message);
}
});
};

View file

@ -1,27 +0,0 @@
// Update the `ghost-admin` client so that it has a proper secret
var _ = require('lodash'),
Promise = require('bluebird'),
crypto = require('crypto'),
models = require('../../../../models'),
adminClient = require('../utils').findModelFixtureEntry('Client', {slug: 'ghost-admin'}),
message = 'Update ghost-admin client fixture';
module.exports = function updateGhostAdminClient(options, logger) {
// ghost-admin should already exist from 003 version
return models.Client.findOne({slug: adminClient.slug}, options)
.then(function (client) {
if (!client) {
return Promise.reject(new Error('Admin client does not exist!'));
}
if (client.get('secret') === 'not_available' || client.get('status') !== 'enabled') {
logger.info(message);
return models.Client.edit(
_.extend({}, adminClient, {secret: crypto.randomBytes(6).toString('hex')}),
_.extend({}, options, {id: client.id})
);
} else {
logger.warn(message);
}
});
};

View file

@ -1,16 +0,0 @@
// Create a new `ghost-frontend` client for use in themes
var models = require('../../../../models'),
frontendClient = require('../utils').findModelFixtureEntry('Client', {slug: 'ghost-frontend'}),
message = 'Add ghost-frontend client fixture';
module.exports = function addGhostFrontendClient(options, logger) {
return models.Client.findOne({slug: frontendClient.slug}, options)
.then(function (client) {
if (!client) {
logger.info(message);
return models.Client.add(frontendClient, options);
} else {
logger.warn(message);
}
});
};

View file

@ -1,32 +0,0 @@
// Clean tags which start with commas, the only illegal char in tags
var models = require('../../../../models'),
Promise = require('bluebird'),
message = 'Cleaning malformed tags';
module.exports = function cleanBrokenTags(options, logger) {
return models.Tag.findAll(options).then(function (tags) {
var tagOps = [];
if (tags) {
tags.each(function (tag) {
var name = tag.get('name'),
updated = name.replace(/^(,+)/, '').trim();
// If we've ended up with an empty string, default to just 'tag'
updated = updated === '' ? 'tag' : updated;
if (name !== updated) {
tagOps.push(tag.save({name: updated}, options));
}
});
if (tagOps.length > 0) {
logger.info(message + '(' + tagOps.length + ')');
return Promise.all(tagOps);
} else {
logger.warn(message);
}
} else {
logger.warn(message);
}
});
};

View file

@ -1,65 +0,0 @@
// Add a new order value to posts_tags based on the existing info
var models = require('../../../../models'),
_ = require('lodash'),
sequence = require('../../../../utils/sequence'),
migrationHasRunFlag,
modelOptions;
function loadTagsForEachPost(posts) {
if (!posts) {
return [];
}
return posts.mapThen(function loadTagsForPost(post) {
return post.load(['tags'], modelOptions);
});
}
function updatePostTagsSortOrder(post, tagId, order) {
var sortOrder = order;
return function doUpdatePivot() {
return post.tags().updatePivot(
{sort_order: sortOrder}, _.extend({}, modelOptions, {query: {where: {tag_id: tagId}}})
);
};
}
function buildTagOpsArray(tagOps, post) {
var order = 0;
return post.related('tags').reduce(function processTag(tagOps, tag) {
if (tag.pivot.get('sort_order') > 0) {
// if any entry in the posts_tags table has already run, we shouldn't run this again
migrationHasRunFlag = true;
}
tagOps.push(updatePostTagsSortOrder(post, tag.id, order));
order += 1;
return tagOps;
}, tagOps);
}
function processPostsArray(postsArray) {
return postsArray.reduce(buildTagOpsArray, []);
}
module.exports = function addPostTagOrder(options, logger) {
modelOptions = options;
migrationHasRunFlag = false;
logger.info('Collecting data on tag order for posts...');
return models.Post.findAll(_.extend({}, modelOptions))
.then(loadTagsForEachPost)
.then(processPostsArray)
.then(function (tagOps) {
if (tagOps.length > 0 && !migrationHasRunFlag) {
logger.info('Updating order on ' + tagOps.length + ' tag relationships (could take a while)...');
return sequence(tagOps).then(function () {
logger.info('Tag order successfully updated');
});
} else {
logger.warn('Updating order on tag relationships');
}
});
};

View file

@ -1,31 +0,0 @@
// Adds a new draft post with information about the new design
var models = require('../../../../models'),
newPost = {
title: 'You\'ve been upgraded to the latest version of Ghost',
slug: 'ghost-0-7',
markdown: 'You\'ve just upgraded to the latest version of Ghost and we\'ve made a few changes that you should probably know about!\n\n## Woah, why does everything look different?\n\nAfter two years and hundreds of thousands of users, we learned a great deal about what was (and wasn\'t) working in the old Ghost admin user interface. What you\'re looking at is Ghost\'s first major UI refresh, with a strong focus on being more usable and robust all round.\n\n![New Design](https://ghost.org/images/zelda.png)\n\nThe main navigation menu, previously located at the top of your screen, has now moved over to the left. This makes it way easier to work with on mobile devices, and has the added benefit of providing ample space for upcoming features!\n\n## Lost and found: Your old posts\n\nFrom talking to many of you we understand that finding old posts in the admin area was a real pain; so we\'ve added a new magical search bar which lets you quickly find posts for editing, without having to scroll endlessly. Take it for a spin!\n\n![Search](https://ghost.org/images/search.gif)\n\nQuestions? Comments? Send us a tweet [@TryGhost](https://twitter.com/tryghost)\n\nOh, and yes you can safely delete this draft post!',
image: null,
featured: false,
page: false,
status: 'draft',
language: 'en_US',
meta_title: null,
meta_description: null
},
message = 'Adding 0.7 upgrade post fixture';
module.exports = function addNewPostFixture(options, logger) {
return models.Post.findOne({slug: newPost.slug, status: 'all'}, options).then(function (post) {
if (!post) {
logger.info(message);
// Set the published_at timestamp, but keep the post as a draft so doesn't appear on the frontend
// This is a hack to ensure that this post appears at the very top of the drafts list, because
// unpublished posts always appear first
newPost.published_at = Date.now();
return models.Post.add(newPost, options);
} else {
logger.warn(message);
}
});
};

View file

@ -1,25 +0,0 @@
module.exports = [
// add jquery setting and privacy info
require('./01-move-jquery-with-alert'),
// change `type` for protected blog `isPrivate` setting
require('./02-update-private-setting-type'),
// change `type` for protected blog `password` setting
require('./03-update-password-setting-type'),
// Update ghost-admin client fixture
require('./04-update-ghost-admin-client'),
// add ghost-frontend client if missing
require('./05-add-ghost-frontend-client'),
// clean up broken tags
require('./06-clean-broken-tags'),
// Add post_tag order
require('./07-add-post-tag-order'),
// Add a new draft post
require('./08-add-post-fixture')
];

View file

@ -1,26 +0,0 @@
// 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(options).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})
);
});
});
};

View file

@ -1,16 +0,0 @@
// 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}, options).then(function (client) {
if (!client) {
logger.info(message);
return models.Client.add(schedulerClient, options);
} else {
logger.warn(message);
}
});
};

View file

@ -1,31 +0,0 @@
// Update the permissions & permissions_roles tables to add entries for clients
var utils = require('../utils'),
resource = 'client';
function getPermissions() {
return utils.findModelFixtures('Permission', {object_type: resource});
}
function getRelations() {
return utils.findPermissionRelationsForObject(resource);
}
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 = getPermissions(),
relationToAdd = getRelations();
return utils.addFixturesForModel(modelToAdd, options).then(function (result) {
printResult(logger, result, 'Adding permissions fixtures for ' + resource + 's');
return utils.addFixturesForRelation(relationToAdd, options);
}).then(function (result) {
printResult(logger, result, 'Adding permissions_roles fixtures for ' + resource + 's');
});
};

View file

@ -1,31 +0,0 @@
// Update the permissions & permissions_roles tables to add entries for subscribers
var utils = require('../utils'),
resource = 'subscriber';
function getPermissions() {
return utils.findModelFixtures('Permission', {object_type: resource});
}
function getRelations() {
return utils.findPermissionRelationsForObject(resource);
}
function printResult(logger, result, message) {
if (result.done === result.expected) {
logger.info(message);
} else {
logger.warn('(' + result.done + '/' + result.expected + ') ' + message);
}
}
module.exports = function addSubscriberPermissions(options, logger) {
var modelToAdd = getPermissions(),
relationToAdd = getRelations();
return utils.addFixturesForModel(modelToAdd, options).then(function (result) {
printResult(logger, result, 'Adding permissions fixtures for ' + resource + 's');
return utils.addFixturesForRelation(relationToAdd, options);
}).then(function (result) {
printResult(logger, result, 'Adding permissions_roles fixtures for ' + resource + 's');
});
};

View file

@ -1,10 +0,0 @@
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'),
// add subscriber permissions and permission_role relations
require('./04-add-subscriber-permissions')
];

View file

@ -1,211 +0,0 @@
var config = require('../../../../config'),
models = require(config.get('paths').corePath + '/server/models'),
api = require(config.get('paths').corePath + '/server/api'),
sequence = require(config.get('paths').corePath + '/server/utils/sequence'),
moment = require('moment'),
_ = require('lodash'),
Promise = require('bluebird'),
messagePrefix = 'Transforming dates to UTC: ',
settingsKey = '006/01',
_private = {};
_private.getTZOffset = function getTZOffset(date) {
return date.getTimezoneOffset();
};
_private.getTZOffsetMax = function getTZOffsetMax() {
return Math.max(Math.abs(new Date('2015-07-01').getTimezoneOffset()), Math.abs(new Date('2015-01-01').getTimezoneOffset()));
};
_private.addOffset = function addOffset(date) {
if (_private.noOffset) {
return moment(date).toDate();
}
return moment(date).add(_private.getTZOffset(date), 'minutes').toDate();
};
/**
* sqlite: stores UTC timestamps, but we will normalize the format to YYYY-MM-DD HH:mm:ss
*/
module.exports = function transformDatesIntoUTC(options, logger) {
var ServerTimezoneOffset = _private.getTZOffsetMax(),
settingsMigrations = null;
// will ensure updated_at fields will not be updated, we take them from the original models
options.importing = true;
return sequence([
function databaseCheck() {
// we have to change the sqlite format, because it stores dates as integer
if (ServerTimezoneOffset === 0 && config.get('database').client === 'mysql') {
return Promise.reject(new Error('skip'));
}
if (config.get('database').client === 'mysql') {
_private.noOffset = false;
} else if (config.get('database').client === 'sqlite3') {
_private.noOffset = true;
}
logger.info(messagePrefix + '(could take a while)...');
return Promise.resolve();
},
function checkIfMigrationAlreadyRan() {
return models.Settings.findOne({key: 'migrations'}, options)
.then(function (result) {
try {
settingsMigrations = JSON.parse(result.attributes.value) || {};
} catch (err) {
return Promise.reject(err);
}
// CASE: migration ran already
if (settingsMigrations.hasOwnProperty(settingsKey)) {
return Promise.reject(new Error('skip'));
}
return Promise.resolve();
});
},
function updatePosts() {
return models.Post.findAll(options).then(function (result) {
if (result.models.length === 0) {
logger.warn(messagePrefix + 'No Posts found');
return;
}
return Promise.mapSeries(result.models, function mapper(post) {
if (post.get('published_at')) {
post.set('published_at', _private.addOffset(post.get('published_at')));
}
if (post.get('updated_at')) {
post.set('updated_at', _private.addOffset(post.get('updated_at')));
}
post.set('created_at', _private.addOffset(post.get('created_at')));
return models.Post.edit(post.toJSON(), _.merge({}, options, {id: post.get('id')}));
}).then(function () {
logger.info(messagePrefix + 'Updated datetime fields for Posts');
});
});
},
function updateUsers() {
return models.User.findAll(options).then(function (result) {
if (result.models.length === 0) {
logger.warn(messagePrefix + 'No Users found');
return;
}
return Promise.mapSeries(result.models, function mapper(user) {
if (user.get('last_login')) {
user.set('last_login', _private.addOffset(user.get('last_login')));
}
if (user.get('updated_at')) {
user.set('updated_at', _private.addOffset(user.get('updated_at')));
}
user.set('created_at', _private.addOffset(user.get('created_at')));
return models.User.edit(user.toJSON(), _.merge({}, options, {id: user.get('id')}));
}).then(function () {
logger.info(messagePrefix + 'Updated datetime fields for Users');
});
});
},
function updateSubscribers() {
return models.Subscriber.findAll(options).then(function (result) {
if (result.models.length === 0) {
logger.warn(messagePrefix + 'No Subscribers found');
return;
}
return Promise.mapSeries(result.models, function mapper(subscriber) {
if (subscriber.get('unsubscribed_at')) {
subscriber.set('unsubscribed_at', _private.addOffset(subscriber.get('unsubscribed_at')));
}
if (subscriber.get('updated_at')) {
subscriber.set('updated_at', _private.addOffset(subscriber.get('updated_at')));
}
subscriber.set('created_at', _private.addOffset(subscriber.get('created_at')));
return models.Subscriber.edit(subscriber.toJSON(), _.merge({}, options, {id: subscriber.get('id')}));
}).then(function () {
logger.info(messagePrefix + 'Updated datetime fields for Subscribers');
});
});
},
function updateSettings() {
return models.Settings.findAll(options).then(function (result) {
if (result.models.length === 0) {
logger.warn(messagePrefix + 'No Settings found');
return;
}
return Promise.mapSeries(result.models, function mapper(settings) {
// migrations was new created, so it already is in UTC
if (settings.get('key') === 'migrations') {
return Promise.resolve();
}
if (settings.get('updated_at')) {
settings.set('updated_at', _private.addOffset(settings.get('updated_at')));
}
settings.set('created_at', _private.addOffset(settings.get('created_at')));
return models.Settings.edit(settings.toJSON(), _.merge({}, options, {id: settings.get('id')}));
}).then(function () {
logger.info(messagePrefix + 'Updated datetime fields for Settings');
});
});
},
function updateAllOtherModels() {
return Promise.mapSeries(['Role', 'Permission', 'Tag', 'App', 'AppSetting', 'AppField', 'Client'], function (model) {
return models[model].findAll(options).then(function (result) {
if (result.models.length === 0) {
logger.warn(messagePrefix + 'No {model} found'.replace('{model}', model));
return;
}
return Promise.mapSeries(result.models, function mapper(object) {
object.set('created_at', _private.addOffset(object.get('created_at')));
if (object.get('updated_at')) {
object.set('updated_at', _private.addOffset(object.get('updated_at')));
}
return models[model].edit(object.toJSON(), _.merge({}, options, {id: object.get('id')}));
}).then(function () {
logger.info(messagePrefix + 'Updated datetime fields for {model}'.replace('{model}', model));
});
});
});
},
function setActiveTimezone() {
var timezone = config.get('forceTimezoneOnMigration') || moment.tz.guess();
return models.Settings.edit({
key: 'activeTimezone',
value: timezone
}, options);
},
function addMigrationSettingsEntry() {
settingsMigrations[settingsKey] = moment().format();
return models.Settings.edit({
key: 'migrations',
value: JSON.stringify(settingsMigrations)
}, options);
},
function updateSettingsCache() {
return api.settings.updateSettingsCache(null, options);
}]
).catch(function (err) {
if (err.message === 'skip') {
logger.warn(messagePrefix + 'Your databases uses UTC datetimes, skip!');
return Promise.resolve();
}
return Promise.reject(err);
});
};

View file

@ -1,3 +0,0 @@
module.exports = [
require('./01-transform-dates-into-utc')
];

View file

@ -1,33 +0,0 @@
var utils = require('../utils'),
permissions = require('../../../../permissions'),
resource = 'theme';
function getPermissions() {
return utils.findModelFixtures('Permission', {object_type: resource});
}
function getRelations() {
return utils.findPermissionRelationsForObject(resource);
}
function printResult(logger, result, message) {
if (result.done === result.expected) {
logger.info(message);
} else {
logger.warn('(' + result.done + '/' + result.expected + ') ' + message);
}
}
module.exports = function addThemePermissions(options, logger) {
var modelToAdd = getPermissions(),
relationToAdd = getRelations();
return utils.addFixturesForModel(modelToAdd, options).then(function (result) {
printResult(logger, result, 'Adding permissions fixtures for ' + resource + 's');
return utils.addFixturesForRelation(relationToAdd, options);
}).then(function (result) {
printResult(logger, result, 'Adding permissions_roles fixtures for ' + resource + 's');
}).then(function () {
return permissions.init(options);
});
};

View file

@ -1,3 +0,0 @@
module.exports = [
require('./01-add-themes-permissions')
];

View file

@ -1,62 +0,0 @@
var config = require('../../../../config'),
_ = require('lodash'),
models = require(config.get('paths').corePath + '/server/models'),
transfomDatesIntoUTC = require(config.get('paths').corePath + '/server/data/migration/fixtures/006/01-transform-dates-into-utc'),
Promise = require('bluebird'),
messagePrefix = 'Fix sqlite format: ',
_private = {};
_private.rerunDateMigration = function rerunDateMigration(options, logger) {
var settingsMigrations, settingsKey = '006/01';
return models.Settings.findOne({key: 'migrations'}, options)
.then(function removeMigrationSettings(result) {
try {
settingsMigrations = JSON.parse(result.attributes.value) || {};
} catch (err) {
return Promise.reject(err);
}
// CASE: migration ran already
if (settingsMigrations.hasOwnProperty(settingsKey)) {
delete settingsMigrations[settingsKey];
return models.Settings.edit({
key: 'migrations',
value: JSON.stringify(settingsMigrations)
}, options);
}
})
.then(function () {
return transfomDatesIntoUTC(options, logger);
});
};
/**
* this migration script is a very special one for people who run their server in UTC and use sqlite3
* 006/01-transform-dates-into-utc had a bug for this case, see what happen because of this bug https://github.com/TryGhost/Ghost/issues/7192
*/
module.exports = function fixSqliteFormat(options, logger) {
// CASE: skip this script when using mysql
if (config.get('database').client === 'mysql') {
logger.warn(messagePrefix + 'This script only runs, when using sqlite as database.');
return Promise.resolve();
}
// CASE: sqlite3 and server is UTC, we check if the date migration was already running
return options.transacting.raw('select created_at from users')
.then(function (users) {
// safety measure
if (!users || !users.length) {
return;
}
// CASE: if type is string and sqlite, then it already has the correct date format
if (!_.isNumber(users[0].created_at)) {
logger.warn(messagePrefix + 'Your dates are in correct format.');
return;
}
return _private.rerunDateMigration(options, logger);
});
};

View file

@ -1,3 +0,0 @@
module.exports = [
require('./01-fix-sqlite-pg-format')
];

View file

@ -3,11 +3,8 @@ var testUtils = require('../utils'),
sinon = require('sinon'),
_ = require('lodash'),
Promise = require('bluebird'),
fixtures = require('../../server/data/migration/fixtures'),
fixtures005 = require('../../server/data/migration/fixtures/005'),
Models = require('../../server/models'),
sandbox = sinon.sandbox.create();
describe('Database Migration (special functions)', function () {
@ -220,59 +217,5 @@ describe('Database Migration (special functions)', function () {
}).catch(done);
});
});
describe('Update', function () {
// We need the roles, and lets add some other perms to simulate the "Update" environment
beforeEach(testUtils.setup('users:roles', 'perms:db', 'perms:init'));
it('should update client permissions correctly', function (done) {
fixtures005[2]({context:{internal:true}}, loggerStub).then(function () {
var props = {
roles: Models.Role.findAll(),
permissions: Models.Permission.findAll({include: ['roles']})
}, permissions;
loggerStub.info.called.should.be.true();
loggerStub.warn.called.should.be.false();
return Promise.props(props).then(function (result) {
should.exist(result);
should.exist(result.roles);
result.roles.length.should.eql(4);
result.roles.at(0).get('name').should.eql('Administrator');
result.roles.at(1).get('name').should.eql('Editor');
result.roles.at(2).get('name').should.eql('Author');
result.roles.at(3).get('name').should.eql('Owner');
// Permissions
result.permissions.length.should.eql(8);
permissions = result.permissions.toJSON();
// DB Perms
permissions[0].name.should.eql('Export database');
permissions[0].should.be.AssignedToRoles(['Administrator']);
permissions[1].name.should.eql('Import database');
permissions[1].should.be.AssignedToRoles(['Administrator']);
permissions[2].name.should.eql('Delete all content');
permissions[2].should.be.AssignedToRoles(['Administrator']);
// Client Perms
permissions[3].name.should.eql('Browse clients');
permissions[3].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[4].name.should.eql('Read clients');
permissions[4].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[5].name.should.eql('Edit clients');
permissions[5].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[6].name.should.eql('Add clients');
permissions[6].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[7].name.should.eql('Delete clients');
permissions[7].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
done();
}).catch(done);
});
});
});
});
});

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -186,35 +186,4 @@ describe('Versioning', function () {
}).catch(done);
});
});
describe('getUpdateTasks', function () {
var logStub;
beforeEach(function () {
logStub = {
info: sandbox.stub(),
warn: sandbox.stub()
};
});
it('`getUpdateFixturesTasks` returns empty array if no tasks are found', function () {
versioning.getUpdateFixturesTasks('999', logStub).should.eql([]);
logStub.info.calledOnce.should.be.true();
});
it('`getUpdateFixturesTasks` returns 8 items for 004', function () {
versioning.getUpdateFixturesTasks('004', logStub).should.be.an.Array().with.lengthOf(8);
logStub.info.calledOnce.should.be.false();
});
it('`getUpdateDatabaseTasks` returns empty array if no tasks are found', function () {
versioning.getUpdateDatabaseTasks('999', logStub).should.eql([]);
logStub.info.calledOnce.should.be.true();
});
it('`getUpdateDatabaseTasks` returns 5 items for 004', function () {
versioning.getUpdateDatabaseTasks('004', logStub).should.be.an.Array().with.lengthOf(5);
logStub.info.calledOnce.should.be.false();
});
});
});