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

Added migration to add settings.{group,flags} columns (#11951)

refs https://github.com/TryGhost/Ghost/issues/10318

- `group`
  - to replace the `type` column, provides a more descriptive name for the columns use
  - for existing sites it will be populated by migrating data from the `type` column in a later migration
  - for new sites a minimal update has been added to `parseDefaultSettings()` to populate the `group` field when settings are created during startup - fixes the NOT NULL constraint on `settings.group`
- `flags`
  - signifies special handling that is different to other settings in a group
  - eg, `PUBLIC,RO` would indicate that the setting is available via unauthenticated endpoints and is read-only
This commit is contained in:
Kevin Ansfield 2020-06-24 11:58:15 +01:00 committed by GitHub
parent 8f1905990d
commit 4a9e57c170
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 94 additions and 21 deletions

View file

@ -0,0 +1,49 @@
const commands = require('../../../schema').commands;
module.exports = {
config: {
transaction: true
},
async up(options) {
function addSettingsColumn(column) {
return {
table: 'settings',
column,
dbIsInCorrectState(columnExists) {
return columnExists === true;
},
operation: commands.addColumn,
operationVerb: 'Adding'
};
}
const columnMigration = commands.createColumnMigration(
addSettingsColumn('group'),
addSettingsColumn('flags')
);
return columnMigration(options);
},
async down(options) {
function removeSettingsColumn(column) {
return {
table: 'settings',
column,
dbIsInCorrectState(columnExists) {
return columnExists === false;
},
operation: commands.dropColumn,
operationVerb: 'Removing'
};
}
const columnMigration = commands.createColumnMigration(
removeSettingsColumn('group'),
removeSettingsColumn('flags')
);
return columnMigration(options);
}
};

View file

@ -54,20 +54,20 @@ function addColumn(tableName, column, transaction, columnSpec) {
});
}
function dropColumn(table, column, transaction) {
return (transaction || db.knex).schema.table(table, function (table) {
function dropColumn(tableName, column, transaction) {
return (transaction || db.knex).schema.table(tableName, function (table) {
table.dropColumn(column);
});
}
function addUnique(table, column, transaction) {
return (transaction || db.knex).schema.table(table, function (table) {
function addUnique(tableName, column, transaction) {
return (transaction || db.knex).schema.table(tableName, function (table) {
table.unique(column);
});
}
function dropUnique(table, column, transaction) {
return (transaction || db.knex).schema.table(table, function (table) {
function dropUnique(tableName, column, transaction) {
return (transaction || db.knex).schema.table(tableName, function (table) {
table.dropUnique(column);
});
}
@ -152,7 +152,7 @@ function createColumnMigration(...migrations) {
const log = createLog(isInCorrectState ? 'warn' : 'info');
log(`${operationVerb} ${table}.${column}`);
log(`${operationVerb} ${table}.${column} column`);
if (!isInCorrectState) {
await operation(table, column, conn, columnDefinition);

View file

@ -145,6 +145,28 @@ module.exports = {
},
settings: {
id: {type: 'string', maxlength: 24, nullable: false, primary: true},
group: {
type: 'string',
maxlength: 50,
nullable: false,
defaultTo: 'core',
validations: {
isIn: [[
'amp',
'core',
'email',
'labs',
'members',
'portal',
'private',
'site',
'slack',
'theme',
'unsplash',
'views'
]]
}
},
key: {type: 'string', maxlength: 50, nullable: false, unique: true},
value: {type: 'text', maxlength: 65535, nullable: true},
type: {
@ -167,6 +189,7 @@ module.exports = {
'views'
]]}
},
flags: {type: 'string', maxlength: 50, nullable: true},
created_at: {type: 'dateTime', nullable: false},
created_by: {type: 'string', maxlength: 24, nullable: false},
updated_at: {type: 'dateTime', nullable: true},

View file

@ -57,6 +57,7 @@ function parseDefaultSettings() {
_.each(defaultSettingsInCategories, function each(settings, categoryName) {
_.each(settings, function each(setting, settingName) {
setting.type = categoryName;
setting.group = categoryName;
setting.key = settingName;
setting.getDefaultValue = function getDefaultValue() {

View file

@ -80,7 +80,7 @@ describe('Settings API', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('codeinjection_head');
testUtils.API.isISO8601(jsonResponse.settings[0].created_at).should.be.true();
done();

View file

@ -179,7 +179,7 @@ describe('Settings API (canary)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('default_locale');
done();
});
@ -242,7 +242,7 @@ describe('Settings API (canary)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('timezone');
done();
});
@ -267,7 +267,7 @@ describe('Settings API (canary)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('active_timezone');
done();
});
@ -292,7 +292,7 @@ describe('Settings API (canary)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('active_timezone');
done();
});

View file

@ -178,7 +178,7 @@ describe('Settings API (v2)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('default_locale');
done();
});
@ -203,7 +203,7 @@ describe('Settings API (v2)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('active_timezone');
done();
});
@ -228,7 +228,7 @@ describe('Settings API (v2)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('ghost_head');
done();
});
@ -253,7 +253,7 @@ describe('Settings API (v2)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('codeinjection_foot');
done();
});

View file

@ -157,7 +157,7 @@ describe('Settings API (v3)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('default_locale');
done();
});
@ -220,7 +220,7 @@ describe('Settings API (v3)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('timezone');
done();
});
@ -245,7 +245,7 @@ describe('Settings API (v3)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('active_timezone');
done();
});
@ -270,7 +270,7 @@ describe('Settings API (v3)', function () {
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'updated_at']);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('active_timezone');
done();
});

View file

@ -19,7 +19,7 @@ const fixtures = require('../../../../core/server/data/schema/fixtures');
*/
describe('DB version integrity', function () {
// Only these variables should need updating
const currentSchemaHash = '7cd198f085844aa5725964069b051189';
const currentSchemaHash = '74b599e66e9d28c591cb7a3d9ec528cf';
const currentFixturesHash = '94cf7dfe95e88022b3515c9664af2e66';
// If this test is failing, then it is likely a change has been made that requires a DB version bump,