2019-09-20 12:44:24 +02:00
|
|
|
'use strict';
|
|
|
|
|
2020-03-05 17:24:46 +01:00
|
|
|
const { replaceIdByPrimaryKey } = require('../utils/primary-key');
|
2020-05-04 11:16:19 +02:00
|
|
|
const { executeBeforeLifecycle, executeAfterLifecycle } = require('../utils/lifecycles');
|
2020-03-05 17:24:46 +01:00
|
|
|
|
2020-04-28 14:05:54 +02:00
|
|
|
/**
|
|
|
|
* @param {Object} opts options
|
|
|
|
* @param {Object} opts.model The ORM model
|
|
|
|
* @param {Object} opts.connectorQuery The ORM queries implementation
|
|
|
|
*/
|
2019-12-17 20:59:57 +01:00
|
|
|
module.exports = function createQuery(opts) {
|
2020-04-23 18:14:12 +02:00
|
|
|
const { model, connectorQuery } = opts;
|
|
|
|
|
|
|
|
return {
|
|
|
|
get model() {
|
|
|
|
return model;
|
|
|
|
},
|
|
|
|
|
|
|
|
get orm() {
|
|
|
|
return model.orm;
|
|
|
|
},
|
|
|
|
|
|
|
|
get primaryKey() {
|
|
|
|
return model.primaryKey;
|
|
|
|
},
|
|
|
|
|
|
|
|
get associations() {
|
|
|
|
return model.associations;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run custom database logic
|
|
|
|
*/
|
|
|
|
custom(mapping) {
|
|
|
|
if (typeof mapping === 'function') {
|
|
|
|
return mapping.bind(this, { model: this.model });
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mapping[this.orm]) {
|
|
|
|
throw new Error(`Missing mapping for orm ${this.orm}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof mapping[this.orm] !== 'function') {
|
|
|
|
throw new Error(`Custom queries must be functions received ${typeof mapping[this.orm]}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mapping[this.model.orm].call(this, { model: this.model });
|
|
|
|
},
|
|
|
|
|
2020-05-04 11:16:19 +02:00
|
|
|
create: createQueryWithLifecycles({ query: 'create', model, connectorQuery }),
|
|
|
|
update: createQueryWithLifecycles({ query: 'update', model, connectorQuery }),
|
|
|
|
delete: createQueryWithLifecycles({ query: 'delete', model, connectorQuery }),
|
|
|
|
find: createQueryWithLifecycles({ query: 'find', model, connectorQuery }),
|
|
|
|
findOne: createQueryWithLifecycles({ query: 'findOne', model, connectorQuery }),
|
2020-05-19 10:55:52 +02:00
|
|
|
findPage: createQueryWithLifecycles({ query: 'findPage', model, connectorQuery }),
|
2020-05-04 11:16:19 +02:00
|
|
|
count: createQueryWithLifecycles({ query: 'count', model, connectorQuery }),
|
|
|
|
search: createQueryWithLifecycles({ query: 'search', model, connectorQuery }),
|
|
|
|
countSearch: createQueryWithLifecycles({ query: 'countSearch', model, connectorQuery }),
|
2020-04-23 18:14:12 +02:00
|
|
|
};
|
2019-09-20 12:44:24 +02:00
|
|
|
};
|
|
|
|
|
2020-04-23 18:14:12 +02:00
|
|
|
// wraps a connectorQuery call with:
|
|
|
|
// - param substitution
|
|
|
|
// - lifecycle hooks
|
2020-05-04 11:16:19 +02:00
|
|
|
const createQueryWithLifecycles = ({ query, model, connectorQuery }) => async (params, ...rest) => {
|
|
|
|
// substitute id for primaryKey value in params
|
2020-04-23 18:14:12 +02:00
|
|
|
const newParams = replaceIdByPrimaryKey(params, model);
|
2020-04-23 18:23:27 +02:00
|
|
|
const queryArguments = [newParams, ...rest];
|
2020-04-20 22:27:20 +02:00
|
|
|
|
2020-04-23 18:14:12 +02:00
|
|
|
// execute before hook
|
2020-05-04 11:16:19 +02:00
|
|
|
await executeBeforeLifecycle(query, model, ...queryArguments);
|
2020-04-20 22:27:20 +02:00
|
|
|
|
2020-04-23 18:14:12 +02:00
|
|
|
// execute query
|
2020-04-24 10:55:09 +02:00
|
|
|
const result = await connectorQuery[query](...queryArguments);
|
2020-04-20 22:27:20 +02:00
|
|
|
|
2020-04-23 18:23:27 +02:00
|
|
|
// execute after hook with result and arguments
|
2020-05-04 11:16:19 +02:00
|
|
|
await executeAfterLifecycle(query, model, result, ...queryArguments);
|
2019-09-20 12:44:24 +02:00
|
|
|
|
2020-04-23 18:14:12 +02:00
|
|
|
// return result
|
|
|
|
return result;
|
|
|
|
};
|