Init db lifecycles manager

This commit is contained in:
Alexandre Bodin 2021-02-16 12:08:35 +01:00
parent 0c56684dfe
commit cefdde18f4
8 changed files with 73 additions and 22 deletions

View File

@ -398,7 +398,7 @@ const createOrUpdateTable = async ({ table, attributes, definition, ORM, model }
module.exports = async ({ ORM, loadedModel, definition, connection, model }) => {
// run migrations
await strapi.db.migrations.runMigration(migrateSchemas, {
await strapi.db.migrations.run(migrateSchemas, {
ORM,
loadedModel,
definition,

View File

@ -301,7 +301,7 @@ module.exports = async ({ models, target }, ctx) => {
const definitionDidChange = await didDefinitionChange(definition, instance);
// run migrations
await strapi.db.migrations.runMigration(migrateSchema, {
await strapi.db.migrations.run(migrateSchema, {
definition,
model: modelInstance,
ORM: instance,

View File

@ -7,6 +7,7 @@ const createConnectorRegistry = require('./connector-registry');
const constants = require('./constants');
const { validateModelSchemas } = require('./validation');
const createMigrationManager = require('./migration-manager');
const createLifecycleManager = require('./lifecycle-manager');
class DatabaseManager {
constructor(strapi) {
@ -23,6 +24,7 @@ class DatabaseManager {
this.models = new Map();
this.migrations = createMigrationManager(this);
this.lifecycles = createLifecycleManager(this);
}
async initialize() {

View File

@ -0,0 +1,35 @@
'use strict';
const debug = require('debug')('strapi-database:lifecycle');
const { isFunction, isNil } = require('lodash/fp');
class LifecycleManager {
constructor(db) {
debug('Initialize lifecycle manager');
this.db = db;
this.lifecycles = [];
}
register(lifecycle) {
debug('Register lifecycle');
this.lifecycles.push(lifecycle);
}
async run(action, model, ...args) {
for (const lifecycle of this.lifecycles) {
if (!isNil(lifecycle.model) && lifecycle.model !== model.uid) {
continue;
}
if (isFunction(lifecycle[action])) {
debug(`Run lifecycle ${action} for model ${model.uid}`);
await lifecycle[action](...args);
}
}
}
}
module.exports = strapi => {
return new LifecycleManager(strapi);
};

View File

@ -14,7 +14,7 @@ class MigrationManager {
this.migrations.push(migration);
}
async runMigration(fn, options, context = {}) {
async run(fn, options, context = {}) {
debug('Run migration');
await this.runBefore(options, context);
await fn(options, context);

View File

@ -4,6 +4,14 @@ const _ = require('lodash');
const createQuery = require('../create-query');
describe('Database queries', () => {
global.strapi = {
db: {
lifecycles: {
run() {},
},
},
};
describe('Substitute id with primaryKey in parameters', () => {
test.each(['create', 'update', 'delete', 'find', 'findOne', 'search', 'count', 'countSearch'])(
'Calling "%s" replaces id by the primaryKey in the params of the model before calling the underlying connector',

View File

@ -3,6 +3,10 @@
const _ = require('lodash');
const executeLifecycle = async (lifecycle, model, ...args) => {
// Run registered lifecycles
await strapi.db.lifecycles.run(lifecycle, model, ...args);
// Run user lifecycles
if (_.has(model, `lifecycles.${lifecycle}`)) {
await model.lifecycles[lifecycle](...args);
}

View File

@ -1,6 +1,5 @@
'use strict';
const _ = require('lodash');
const { capitalize } = require('lodash/fp');
const { getService } = require('../../utils');
@ -26,23 +25,26 @@ module.exports = async () => {
await getService('locales').setDefaultLocale(DEFAULT_LOCALE);
}
Object.values(strapi.models).forEach(model => {
if (getService('content-types').isLocalized(model)) {
// TODO: support adding lifecycles programmatically or connecting to a database event handler to avoid conflicts with existing lifecycles fonctions
_.set(model, 'lifecycles.beforeCreate', async data => {
if (!data.locale) {
data.locale = await getService('locales').getDefaultLocale();
}
Object.values(strapi.models)
.filter(model => getService('content-types').isLocalized(model))
.forEach(model => {
strapi.db.lifecycles.register({
model: model.uid,
async beforeCreate(data) {
if (!data.locale) {
data.locale = await getService('locales').getDefaultLocale();
}
},
async afterCreate(entry) {
await getService('localizations').addLocalizations(entry, { model });
},
async afterUpdate(entry) {
await getService('localizations').updateNonLocalizedFields(entry, { model });
},
async afterDelete() {
// TODO/ implement
// await getService('localizations').updateDeletedLocalization(entry, { model });
},
});
_.set(model, 'lifecycles.afterCreate', async entry => {
await getService('localizations').addLocalizations(entry, { model });
});
_.set(model, 'lifecycles.afterUpdate', async entry => {
await getService('localizations').updateNonLocalizedFields(entry, { model });
});
}
});
});
};