forest-express-sequelize
Version:
Official Express/Sequelize Liana for Forest
188 lines (186 loc) • 8.21 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
require("core-js/modules/es.regexp.exec.js");
require("core-js/modules/es.string.replace.js");
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/es.promise.js");
var _forestExpress = require("forest-express");
var _lodash = _interopRequireDefault(require("lodash"));
var _moment = _interopRequireDefault(require("moment"));
var _database = require("../utils/database");
var _orm = _interopRequireDefault(require("../utils/orm"));
var _queryOptions = _interopRequireDefault(require("./query-options"));
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function LineStatGetter(model, params, options, user) {
const schema = _forestExpress.Schemas.schemas[model.name];
const timeRange = params.timeRange.toLowerCase();
function getAggregateField() {
// NOTICE: As MySQL cannot support COUNT(table_name.*) syntax, fieldName cannot be '*'.
const fieldName = params.aggregateFieldName || schema.primaryKeys[0] || schema.fields[0].field;
return `${schema.name}.${_orm.default.getColumnName(schema, fieldName)}`;
}
function getGroupByDateField() {
return `${schema.name}.${_orm.default.getColumnName(schema, params.groupByFieldName)}`;
}
const groupByDateField = getGroupByDateField();
function getGroupByDateFieldFormatedForMySQL(currentTimeRange) {
const groupByDateFieldFormated = `\`${groupByDateField.replace('.', '`.`')}\``;
switch (currentTimeRange) {
case 'day':
return options.Sequelize.fn('DATE_FORMAT', options.Sequelize.col(groupByDateField), '%Y-%m-%d 00:00:00');
case 'week':
return options.Sequelize.literal(`DATE_FORMAT(DATE_SUB(${groupByDateFieldFormated}, \
INTERVAL ((7 + WEEKDAY(${groupByDateFieldFormated})) % 7) DAY), '%Y-%m-%d 00:00:00')`);
case 'month':
return options.Sequelize.fn('DATE_FORMAT', options.Sequelize.col(groupByDateField), '%Y-%m-01 00:00:00');
case 'year':
return options.Sequelize.fn('DATE_FORMAT', options.Sequelize.col(groupByDateField), '%Y-01-01 00:00:00');
default:
return null;
}
}
function getGroupByDateFieldFormatedForMSSQL(currentTimeRange) {
const groupByDateFieldFormated = `[${groupByDateField.replace('.', '].[')}]`;
switch (currentTimeRange) {
case 'day':
return options.Sequelize.fn('FORMAT', options.Sequelize.col(groupByDateField), 'yyyy-MM-dd 00:00:00');
case 'week':
return options.Sequelize.literal(`FORMAT(DATEADD(DAY, -DATEPART(dw,${groupByDateFieldFormated}),\
${groupByDateFieldFormated}), 'yyyy-MM-dd 00:00:00')`);
case 'month':
return options.Sequelize.fn('FORMAT', options.Sequelize.col(groupByDateField), 'yyyy-MM-01 00:00:00');
case 'year':
return options.Sequelize.fn('FORMAT', options.Sequelize.col(groupByDateField), 'yyyy-01-01 00:00:00');
default:
return null;
}
}
function getGroupByDateFieldFormatedForSQLite(currentTimeRange) {
switch (currentTimeRange) {
case 'day':
{
return options.Sequelize.fn('STRFTIME', '%Y-%m-%d', options.Sequelize.col(groupByDateField));
}
case 'week':
{
return options.Sequelize.fn('STRFTIME', '%Y-%W', options.Sequelize.col(groupByDateField));
}
case 'month':
{
return options.Sequelize.fn('STRFTIME', '%Y-%m-01', options.Sequelize.col(groupByDateField));
}
case 'year':
{
return options.Sequelize.fn('STRFTIME', '%Y-01-01', options.Sequelize.col(groupByDateField));
}
default:
return null;
}
}
function getGroupByDateInterval() {
if ((0, _database.isMySQL)(model.sequelize)) {
return [getGroupByDateFieldFormatedForMySQL(timeRange), 'date'];
}
if ((0, _database.isMSSQL)(model.sequelize)) {
return [getGroupByDateFieldFormatedForMSSQL(timeRange), 'date'];
}
if ((0, _database.isSQLite)(model.sequelize)) {
return [getGroupByDateFieldFormatedForSQLite(timeRange), 'date'];
}
return [options.Sequelize.fn('to_char', options.Sequelize.fn('date_trunc', params.timeRange, options.Sequelize.literal(`"${getGroupByDateField().replace('.', '"."')}" at time zone '${params.timezone}'`)), 'YYYY-MM-DD 00:00:00'), 'date'];
}
function getFormat() {
switch (timeRange) {
case 'day':
return 'DD/MM/YYYY';
case 'week':
return '[W]W-GGGG';
case 'month':
return 'MMM YY';
case 'year':
return 'YYYY';
default:
return null;
}
}
function fillEmptyDateInterval(records) {
if (records.length) {
let sqlFormat = 'YYYY-MM-DD 00:00:00';
if ((0, _database.isSQLite)(model.sequelize) && timeRange === 'week') {
sqlFormat = 'YYYY-WW';
}
const firstDate = (0, _moment.default)(records[0].label, sqlFormat);
const lastDate = (0, _moment.default)(records[records.length - 1].label, sqlFormat);
for (let i = firstDate; i.toDate() <= lastDate.toDate(); i = i.add(1, timeRange)) {
const label = i.format(sqlFormat);
if (!_lodash.default.find(records, {
label
})) {
records.push({
label,
values: {
value: 0
}
});
}
}
records = _lodash.default.sortBy(records, 'label');
return _lodash.default.map(records, function (record) {
return {
label: (0, _moment.default)(record.label, sqlFormat).format(getFormat()),
values: record.values
};
});
}
return records;
}
function getAggregate() {
return [options.Sequelize.fn(params.aggregator.toLowerCase(), options.Sequelize.col(getAggregateField())), 'value'];
}
function getGroupBy() {
return (0, _database.isMSSQL)(model.sequelize) ? [getGroupByDateFieldFormatedForMSSQL(timeRange)] : [options.Sequelize.literal('1')];
}
function getOrder() {
return (0, _database.isMSSQL)(model.sequelize) ? [getGroupByDateFieldFormatedForMSSQL(timeRange)] : [options.Sequelize.literal('1')];
}
this.perform = async function () {
const {
filter,
timezone
} = params;
const scopeFilters = await _forestExpress.scopeManager.getScopeForUser(user, model.name, true);
const queryOptions = new _queryOptions.default(model, {
includeRelations: true
});
await queryOptions.filterByConditionTree(filter, timezone);
await queryOptions.filterByConditionTree(scopeFilters, timezone);
const sequelizeOptions = _objectSpread(_objectSpread({}, queryOptions.sequelizeOptions), {}, {
attributes: [getGroupByDateInterval(), getAggregate()],
group: getGroupBy(),
order: getOrder(),
raw: true
});
// do not load related properties
if (sequelizeOptions.include) {
sequelizeOptions.include = sequelizeOptions.include.map(function (includeProperties) {
return _objectSpread(_objectSpread({}, includeProperties), {}, {
attributes: []
});
});
}
const records = await model.unscoped().findAll(sequelizeOptions);
return {
value: fillEmptyDateInterval(records.map(function (record) {
return {
label: record.date,
values: {
value: parseInt(record.value, 10)
}
};
}))
};
};
}
module.exports = LineStatGetter;
;