0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Updated post model queries to raw knex queries (#11246)

no issue

We split `posts` table into 2 in v3 with a new `posts_meta` table. Since migrations always use the version of code which is being migrated to - in this case the Post model - which in v3 relies on the posts_meta table, `2.x` migrations relying on post model will fail as it doesn't exist in the expected state. This PR updates all 2.x migrations using `models.Post` to use knex queries directly to access database and perform operations.
This commit is contained in:
Rishabh Garg 2019-10-17 10:36:18 +05:30 committed by GitHub
parent 2358c65535
commit d8e65d46e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 56 deletions

View file

@ -1,7 +1,6 @@
const _ = require('lodash'),
Promise = require('bluebird'),
common = require('../../../../lib/common'),
models = require('../../../../models'),
converters = require('../../../../lib/mobiledoc/converters'),
message1 = 'Updating posts: apply new editor format and set comment_id field.',
message2 = 'Updated posts: apply new editor format and set comment_id field.',
@ -38,14 +37,17 @@ module.exports.up = (options) => {
common.logging.info(message1);
return models.Post.findAll(_.merge({columns: postAllColumns}, localOptions))
.then(function (posts) {
return Promise.map(posts.models, function (post) {
// @NOTE: raw knex query, because of https://github.com/TryGhost/Ghost/issues/9983
return localOptions
.transacting('posts')
.select(postAllColumns)
.then((posts) => {
return Promise.map(posts, function (post) {
let mobiledoc;
let html;
try {
mobiledoc = JSON.parse(post.get('mobiledoc') || null);
mobiledoc = JSON.parse(post.mobiledoc || null);
if (!mobiledoc) {
mobiledoc = converters.mobiledocConverter.blankStructure();
@ -58,18 +60,19 @@ module.exports.up = (options) => {
// CASE: convert all old editor posts to the new editor format
// CASE: if mobiledoc field is null, we auto set a blank structure in the model layer
// CASE: if html field is null, we auto generate the html in the model layer
if (mobiledoc && post.get('html') && post.get('html').match(/^<div class="kg-card-markdown">/)) {
if (mobiledoc && post.html && post.html.match(/^<div class="kg-card-markdown">/)) {
html = converters.mobiledocConverter.render(mobiledoc);
}
return models.Post.edit({
comment_id: post.get('comment_id') || post.id,
html: html || post.get('html'),
mobiledoc: JSON.stringify(mobiledoc)
}, _.merge({id: post.id}, localOptions));
return localOptions
.transacting('posts')
.where('id', '=', post.id)
.update({
comment_id: post.comment_id || post.id,
html: html || post.html,
mobiledoc: JSON.stringify(mobiledoc)
});
}, {concurrency: 100});
})
.then(() => {
}).then(() => {
common.logging.info(message2);
});
};
@ -83,26 +86,30 @@ module.exports.down = (options) => {
}, options);
common.logging.info(message3);
return models.Post.findAll(_.merge({columns: postAllColumns}, localOptions))
.then(function (posts) {
return Promise.map(posts.models, function (post) {
return localOptions
.transacting('posts')
.select(postAllColumns)
.then((posts) => {
return Promise.map(posts, function (post) {
let version = 1;
let html;
let mobiledoc = JSON.parse(post.get('mobiledoc') || null);
let mobiledoc = JSON.parse(post.mobiledoc || null);
if (!mobiledocIsCompatibleWithV1(mobiledoc)) {
version = 2;
}
// CASE: revert: all new editor posts to the old editor format
if (mobiledoc && post.get('html')) {
if (mobiledoc && post.html) {
html = converters.mobiledocConverter.render(mobiledoc, version);
}
return models.Post.edit({
html: html || post.get('html')
}, _.merge({id: post.id}, localOptions));
return localOptions
.transacting('posts')
.where('id', '=', post.id)
.update({
html: html || post.html
});
}, {concurrency: 100});
})
.then(() => {

View file

@ -1,6 +1,5 @@
const _ = require('lodash'),
common = require('../../../../lib/common'),
models = require('../../../../models'),
message1 = 'Removing demo post.',
message2 = 'Removed demo post.',
message3 = 'Rollback: Bring back demo post.',
@ -34,24 +33,27 @@ module.exports.up = (options) => {
migrating: true
}, options);
return models.Post.findOne({slug: 'v2-demo-post', status: 'all'}, localOptions)
.then(function (postModel) {
if (!postModel) {
return localOptions
.transacting('posts')
.where('slug', 'v2-demo-post')
.where('status', 'all')
.select().then((posts) => {
if (!posts || posts.length === 0) {
common.logging.warn(message4);
return;
}
common.logging.info(message1);
let post = posts[0];
// @NOTE: raw knex query, because of https://github.com/TryGhost/Ghost/issues/9983
return options
.transacting('posts_authors')
.where('post_id', postModel.id)
.where('post_id', post.id)
.del()
.then(() => {
return options
.transacting('posts')
.where('id', postModel.id)
.where('id', post.id)
.del();
});
})
@ -67,14 +69,17 @@ module.exports.down = (options) => {
migrating: true
}, options);
return models.Post.findOne({slug: 'v2-demo-post', status: 'all'}, localOptions)
.then(function (postModel) {
if (postModel) {
return localOptions
.transacting('posts')
.where('slug', 'v2-demo-post')
.where('status', 'all')
.select().then((posts) => {
if (posts && posts.length > 0) {
common.logging.warn(message5);
return;
}
common.logging.info(message3);
return models.Post.add(demoPost, localOptions);
return localOptions.transacting('posts').insert(demoPost);
});
};

View file

@ -1,4 +1,3 @@
const models = require('../../../../models');
const common = require('../../../../lib/common');
const config = require('../../../../config');
const {URL} = require('url');
@ -32,19 +31,20 @@ module.exports.up = (options) => {
// perform a specific query for the type of canonical URLs we're looking for
// so we're not fetching and manually looping over a ton of post models
return models.Posts
.forge()
.query((qb) => {
qb.where('canonical_url', 'like', '/%');
qb.whereNot('canonical_url', 'like', '//%');
})
.fetch(localOptions)
.then((posts) => {
return localOptions
.transacting('posts')
.where('canonical_url', 'like', '/%')
.whereNot('canonical_url', 'like', '//%')
.select().then((posts) => {
if (posts) {
return Promise.mapSeries(posts, (post) => {
const canonicalUrl = post.get('canonical_url').replace('/', url.pathname);
post.set('canonical_url', canonicalUrl);
return post.save(null, localOptions);
const canonicalUrl = post.canonical_url.replace('/', url.pathname);
return localOptions
.transacting('posts')
.where('id', '=', post.id)
.update({
canonical_url: canonicalUrl
});
}).then(() => {
common.logging.info(`Added subdirectory prefix to canonical_url in ${posts.length} posts`);
});
@ -75,18 +75,19 @@ module.exports.down = (options) => {
return Promise.resolve();
}
return models.Posts
.forge()
.query((qb) => {
qb.where('canonical_url', 'LIKE', `${url.pathname}%`);
})
.fetch()
.then((posts) => {
return localOptions
.transacting('posts')
.where('canonical_url', 'like', `${url.pathname}%`)
.select().then((posts) => {
if (posts) {
return Promise.mapSeries(posts, (post) => {
const canonicalUrl = post.get('canonical_url').replace(url.pathname, '/');
post.set('canonical_url', canonicalUrl);
return post.save(null, localOptions);
const canonicalUrl = post.canonical_url.replace(url.pathname, '/');
return localOptions
.transacting('posts')
.where('id', '=', post.id)
.update({
canonical_url: canonicalUrl
});
}).then(() => {
common.logging.info(`Removed subdirectory prefix from canonical_url in ${posts.length} posts`);
});