UNPKG

forest-express-sequelize

Version:

Official Express/Sequelize Liana for Forest

188 lines (186 loc) 8.21 kB
"use strict"; 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;