@cloudbase/js-sdk
Version:
cloudbase javascript sdk
230 lines (229 loc) • 9.07 kB
JavaScript
import { isQueryCommand, isComparisonCommand, QUERY_COMMANDS_LITERAL } from '../commands/query';
import { isLogicCommand, LOGIC_COMMANDS_LITERAL } from '../commands/logic';
import { SYMBOL_UNSET_FIELD_NAME } from '../helper/symbol';
import { getType, isObject, isArray, isRegExp } from '../utils/type';
import { operatorToString } from '../operator-map';
import { flattenQueryObject, isConversionRequired, encodeInternalDataType } from './common';
var QuerySerializer = (function () {
function QuerySerializer() {
}
QuerySerializer.encode = function (query) {
var encoder = new QueryEncoder();
return encoder.encodeQuery(query);
};
return QuerySerializer;
}());
export { QuerySerializer };
var QueryEncoder = (function () {
function QueryEncoder() {
}
QueryEncoder.prototype.encodeQuery = function (query, key) {
var _a;
if (isConversionRequired(query)) {
if (isLogicCommand(query)) {
return this.encodeLogicCommand(query);
}
else if (isQueryCommand(query)) {
return this.encodeQueryCommand(query);
}
else {
return _a = {}, _a[key] = this.encodeQueryObject(query), _a;
}
}
else {
if (isObject(query)) {
return this.encodeQueryObject(query);
}
else {
return query;
}
}
};
QueryEncoder.prototype.encodeRegExp = function (query) {
return {
$regex: query.source,
$options: query.flags
};
};
QueryEncoder.prototype.encodeLogicCommand = function (query) {
var _a, _b, _c, _d, _e, _f, _g;
var _this = this;
switch (query.operator) {
case LOGIC_COMMANDS_LITERAL.NOR:
case LOGIC_COMMANDS_LITERAL.AND:
case LOGIC_COMMANDS_LITERAL.OR: {
var $op = operatorToString(query.operator);
var subqueries = query.operands.map(function (oprand) {
return _this.encodeQuery(oprand, query.fieldName);
});
return _a = {},
_a[$op] = subqueries,
_a;
}
case LOGIC_COMMANDS_LITERAL.NOT: {
var $op = operatorToString(query.operator);
var operatorExpression = query.operands[0];
if (isRegExp(operatorExpression)) {
return _b = {},
_b[query.fieldName] = (_c = {},
_c[$op] = this.encodeRegExp(operatorExpression),
_c),
_b;
}
else {
var subqueries = this.encodeQuery(operatorExpression)[query.fieldName];
return _d = {},
_d[query.fieldName] = (_e = {},
_e[$op] = subqueries,
_e),
_d;
}
}
default: {
var $op = operatorToString(query.operator);
if (query.operands.length === 1) {
var subquery = this.encodeQuery(query.operands[0]);
return _f = {},
_f[$op] = subquery,
_f;
}
else {
var subqueries = query.operands.map(this.encodeQuery.bind(this));
return _g = {},
_g[$op] = subqueries,
_g;
}
}
}
};
QueryEncoder.prototype.encodeQueryCommand = function (query) {
if (isComparisonCommand(query)) {
return this.encodeComparisonCommand(query);
}
else {
return this.encodeComparisonCommand(query);
}
};
QueryEncoder.prototype.encodeComparisonCommand = function (query) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
if (query.fieldName === SYMBOL_UNSET_FIELD_NAME) {
throw new Error('Cannot encode a comparison command with unset field name');
}
var $op = operatorToString(query.operator);
switch (query.operator) {
case QUERY_COMMANDS_LITERAL.EQ:
case QUERY_COMMANDS_LITERAL.NEQ:
case QUERY_COMMANDS_LITERAL.LT:
case QUERY_COMMANDS_LITERAL.LTE:
case QUERY_COMMANDS_LITERAL.GT:
case QUERY_COMMANDS_LITERAL.GTE:
case QUERY_COMMANDS_LITERAL.ELEM_MATCH:
case QUERY_COMMANDS_LITERAL.EXISTS:
case QUERY_COMMANDS_LITERAL.SIZE:
case QUERY_COMMANDS_LITERAL.MOD: {
return _a = {},
_a[query.fieldName] = (_b = {},
_b[$op] = encodeInternalDataType(query.operands[0]),
_b),
_a;
}
case QUERY_COMMANDS_LITERAL.IN:
case QUERY_COMMANDS_LITERAL.NIN:
case QUERY_COMMANDS_LITERAL.ALL: {
return _c = {},
_c[query.fieldName] = (_d = {},
_d[$op] = encodeInternalDataType(query.operands),
_d),
_c;
}
case QUERY_COMMANDS_LITERAL.GEO_NEAR: {
var options = query.operands[0];
return _e = {},
_e[query.fieldName] = {
$nearSphere: {
$geometry: options.geometry.toJSON(),
$maxDistance: options.maxDistance,
$minDistance: options.minDistance
}
},
_e;
}
case QUERY_COMMANDS_LITERAL.GEO_WITHIN: {
var options = query.operands[0];
return _f = {},
_f[query.fieldName] = {
$geoWithin: {
$geometry: options.geometry.toJSON()
}
},
_f;
}
case QUERY_COMMANDS_LITERAL.GEO_INTERSECTS: {
var options = query.operands[0];
return _g = {},
_g[query.fieldName] = {
$geoIntersects: {
$geometry: options.geometry.toJSON()
}
},
_g;
}
default: {
return _h = {},
_h[query.fieldName] = (_j = {},
_j[$op] = encodeInternalDataType(query.operands[0]),
_j),
_h;
}
}
};
QueryEncoder.prototype.encodeQueryObject = function (query) {
var flattened = flattenQueryObject(query);
for (var key in flattened) {
var val = flattened[key];
if (isLogicCommand(val)) {
flattened[key] = val._setFieldName(key);
var condition = this.encodeLogicCommand(flattened[key]);
this.mergeConditionAfterEncode(flattened, condition, key);
}
else if (isComparisonCommand(val)) {
flattened[key] = val._setFieldName(key);
var condition = this.encodeComparisonCommand(flattened[key]);
this.mergeConditionAfterEncode(flattened, condition, key);
}
else if (isConversionRequired(val)) {
flattened[key] = encodeInternalDataType(val);
}
}
return flattened;
};
QueryEncoder.prototype.mergeConditionAfterEncode = function (query, condition, key) {
if (!condition[key]) {
delete query[key];
}
for (var conditionKey in condition) {
if (query[conditionKey]) {
if (isArray(query[conditionKey])) {
query[conditionKey] = query[conditionKey].concat(condition[conditionKey]);
}
else if (isObject(query[conditionKey])) {
if (isObject(condition[conditionKey])) {
Object.assign(query, condition);
}
else {
console.warn("unmergable condition, query is object but condition is ".concat(getType(condition), ", can only overwrite"), condition, key);
query[conditionKey] = condition[conditionKey];
}
}
else {
console.warn("to-merge query is of type ".concat(getType(query), ", can only overwrite"), query, condition, key);
query[conditionKey] = condition[conditionKey];
}
}
else {
query[conditionKey] = condition[conditionKey];
}
}
};
return QueryEncoder;
}());