cosmos-db-repositories
Version:
cosmos-db repositories
214 lines (213 loc) • 7.89 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseOrderProperty = exports.parseOrderProperties = void 0;
const time_utils_1 = __importDefault(require("./time.utils"));
const build = ({ searchValue, searchFields, matchFields, orderBy }) => {
let query = 'SELECT * FROM c';
const parameters = [];
const andOperations = [];
const orOperations = [];
if (searchValue && searchFields.length) {
parameters.push({ name: '@q', value: searchValue });
searchFields.forEach(it => orOperations.push('CONTAINS(LOWER(c.' + it + '), @q)'));
}
const validFields = Object.keys(matchFields).filter(it => {
const val = matchFields[it];
if (val === undefined || val === null || val.length === 0) {
return false;
}
if (val instanceof Array) {
return val.filter(it => it !== null && it !== undefined && it.length > 0).length > 0;
}
return true;
});
validFields.forEach(it => {
const val = matchFields[it];
let key = it.split('.').join('_');
if (key[0] === '!') {
key = key.substring(1);
}
const paramKey = key.split('|').join('_');
if (val instanceof Array) {
if (time_utils_1.default.isDateTimeFormat(val[0])) {
parameters.push({ name: '@from_' + paramKey, value: time_utils_1.default.toUTC(val[0]) });
parameters.push({ name: '@to_' + paramKey, value: time_utils_1.default.toUTC(val[1] || new Date().toISOString()) });
}
else {
parameters.push({ name: '@' + paramKey, value: val });
}
}
else {
let value = val;
if (value[0] === '!') {
value = value.substring(1);
}
if (time_utils_1.default.isDateTimeFormat(value)) {
parameters.push({ name: '@' + paramKey, value: time_utils_1.default.toUTC(value) });
}
else {
parameters.push({ name: '@' + paramKey, value });
}
}
});
validFields.forEach(it => {
const val = matchFields[it];
const key = it.split('.').join('_');
let columnName = it;
let valueName = key;
if (it[0] === '!') {
columnName = it.substring(1);
valueName = key.substring(1);
}
if (val instanceof Array) {
const valueNames = valueName.split('|');
if (time_utils_1.default.isDateTimeFormat(val[0])) {
if (it[0] === '!') {
andOperations.push('(NOT IS_DEFINED(c.' + columnName + ') OR (c.' + columnName + ' >= @from_' + valueName + ') AND c.' + columnName + ' <= @to_' + valueName + ')');
}
else if (valueNames.length > 1) {
const valueNameJoined = valueNames.join('_');
const ors = valueNames.map(o => 'c.' + o + ' >= @from_' + valueNameJoined + ' AND ' + 'c.' + o + ' <= @to_' + valueNameJoined).map(o => '(' + o + ')');
andOperations.push('(' + ors.join(' OR ') + ')');
}
else {
andOperations.push('c.' + it + ' >= @from_' + valueName);
andOperations.push('c.' + it + ' <= @to_' + valueName);
}
}
else {
andOperations.push('ARRAY_CONTAINS(@' + valueName + ', c.' + it + ')');
}
}
else if (val[0] === '!') {
andOperations.push('c.' + it + ' != @' + valueName);
}
else {
const tokens = it.split('.');
if (tokens.length > 1) {
const collectionName = tokens[0];
const propertyName = tokens[1];
andOperations.push('ARRAY_CONTAINS(c.' + collectionName + ', {"' + propertyName + '": @' + valueName + '}, true)');
}
else {
andOperations.push('c.' + it + ' = @' + valueName);
}
}
});
if (orOperations.length || andOperations.length) {
query += ' WHERE 1=1';
}
if (orOperations.length) {
if (orOperations.length === 1) {
query += ' AND ' + orOperations.join(' OR ');
}
else {
query += ' AND (' + orOperations.join(' OR ') + ')';
}
}
if (andOperations.length) {
query += ' AND ' + andOperations.join(' AND ');
}
const orderByProperties = (0, exports.parseOrderProperties)(orderBy);
if (orderByProperties.length) {
query += ' ORDER BY ' + orderByProperties
.map(it => {
if (it.collection) {
return 'ARRAY_LENGTH(c.' + it.property + ') ' + it.direction;
}
return 'c.' + it.property + ' ' + it.direction;
})
.join(', ');
}
return { query, parameters };
};
const parseOrderProperties = (orderBy) => {
if (!orderBy || !orderBy.trim().length) {
return [];
}
return orderBy.split(',').map(exports.parseOrderProperty);
};
exports.parseOrderProperties = parseOrderProperties;
const parseOrderProperty = (orderBy) => {
if (!orderBy || !orderBy.trim().length) {
return { property: orderBy };
}
// ![projects]?
let property = orderBy;
const direction = property[0] === '!' ? 'ASC' : 'DESC';
if (property[0] === '!') {
property = property.substring(1);
}
const optional = property[property.length - 1] === '?';
if (optional) {
property = property.substring(0, property.length - 1);
}
const collection = property[0] === '[' && property[property.length - 1] === ']';
if (collection) {
property = property.substring(1, property.length - 1);
}
return {
property,
optional,
collection,
direction
};
};
exports.parseOrderProperty = parseOrderProperty;
class BuildInstance {
constructor() {
this.template = 'SELECT{top}{distinct} {columns} FROM c{where} {orderBy}';
this.isDistinct = false;
this.topValue = 0;
this.listOfColumns = [];
this.whereQuery = '';
this.sortDirection = '';
this.sortProperties = [];
}
columns(...columns) {
columns.forEach(it => this.listOfColumns.push(it));
return this;
}
distinct(isDistinct) {
this.isDistinct = isDistinct === undefined ? true : isDistinct;
return this;
}
sort(...columns) {
columns.forEach(it => this.sortProperties.push(it));
if (columns.length === 0) {
this.listOfColumns.forEach(it => this.sortProperties.push(it));
}
return this;
}
asc() {
this.sortDirection = 'ASC';
return this;
}
top(top) {
this.topValue = top;
return this;
}
where(where) {
this.whereQuery = where;
return this;
}
desc() {
this.sortDirection = 'DESC';
return this;
}
build() {
return this.template
.replace('{top}', this.topValue ? ' TOP ' + this.topValue : '')
.replace('{distinct}', this.isDistinct ? ' DISTINCT' : '')
.replace('{columns}', this.listOfColumns.length ? this.listOfColumns.map(it => 'c.' + it).join(', ') : '*')
.replace('{where}', this.whereQuery ? ' WHERE ' + this.whereQuery : '')
.replace('{orderBy}', this.sortProperties.length ? 'ORDER BY ' + this.sortProperties.map(it => ('c.' + it + ' ' + this.sortDirection).trim()).join(', ') : '');
}
}
const instance = () => new BuildInstance();
exports.default = {
build, instance
};