123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- const query_1 = require("../commands/query");
- const logic_1 = require("../commands/logic");
- const symbol_1 = require("../helper/symbol");
- const type_1 = require("../utils/type");
- const operator_map_1 = require("../operator-map");
- const common_1 = require("./common");
- const utils_1 = require("../utils/utils");
- const validate_1 = require("../validate");
- class QuerySerializer {
- constructor() { }
- static encode(query) {
- const encoder = new QueryEncoder();
- return encoder.encodeQuery(query);
- }
- static encodeEJSON(query) {
- const encoder = new QueryEncoder();
- return utils_1.stringifyByEJSON(encoder.encodeQuery(query));
- }
- }
- exports.QuerySerializer = QuerySerializer;
- class QueryEncoder {
- encodeQuery(query, key) {
- if (common_1.isConversionRequired(query)) {
- if (logic_1.isLogicCommand(query)) {
- return this.encodeLogicCommand(query);
- }
- else if (query_1.isQueryCommand(query)) {
- return this.encodeQueryCommand(query);
- }
- else if (type_1.isRegExp(query)) {
- return { [key]: this.encodeRegExp(query) };
- }
- else if (type_1.isDate(query)) {
- return { [key]: query };
- }
- else {
- return { [key]: this.encodeQueryObject(query) };
- }
- }
- else {
- if (type_1.isObject(query)) {
- return this.encodeQueryObject(query);
- }
- else {
- return query;
- }
- }
- }
- encodeRegExp(query) {
- return {
- $regularExpression: {
- pattern: query.source,
- options: query.flags
- }
- };
- }
- encodeLogicCommand(query) {
- switch (query.operator) {
- case logic_1.LOGIC_COMMANDS_LITERAL.NOR:
- case logic_1.LOGIC_COMMANDS_LITERAL.AND:
- case logic_1.LOGIC_COMMANDS_LITERAL.OR: {
- const $op = operator_map_1.operatorToString(query.operator);
- const subqueries = query.operands.map((oprand) => this.encodeQuery(oprand, query.fieldName));
- return {
- [$op]: subqueries
- };
- }
- case logic_1.LOGIC_COMMANDS_LITERAL.NOT: {
- const $op = operator_map_1.operatorToString(query.operator);
- const operatorExpression = query.operands[0];
- if (type_1.isRegExp(operatorExpression)) {
- return {
- [query.fieldName]: {
- [$op]: this.encodeRegExp(operatorExpression)
- }
- };
- }
- else {
- const subqueries = this.encodeQuery(operatorExpression)[query.fieldName];
- return {
- [query.fieldName]: {
- [$op]: subqueries
- }
- };
- }
- }
- default: {
- const $op = operator_map_1.operatorToString(query.operator);
- if (query.operands.length === 1) {
- const subquery = this.encodeQuery(query.operands[0]);
- return {
- [$op]: subquery
- };
- }
- else {
- const subqueries = query.operands.map(this.encodeQuery.bind(this));
- return {
- [$op]: subqueries
- };
- }
- }
- }
- }
- encodeQueryCommand(query) {
- if (query_1.isComparisonCommand(query)) {
- return this.encodeComparisonCommand(query);
- }
- else {
- return this.encodeComparisonCommand(query);
- }
- }
- encodeComparisonCommand(query) {
- if (query.fieldName === symbol_1.SYMBOL_UNSET_FIELD_NAME) {
- throw new Error('Cannot encode a comparison command with unset field name');
- }
- const $op = operator_map_1.operatorToString(query.operator);
- switch (query.operator) {
- case query_1.QUERY_COMMANDS_LITERAL.EQ:
- case query_1.QUERY_COMMANDS_LITERAL.NEQ:
- case query_1.QUERY_COMMANDS_LITERAL.LT:
- case query_1.QUERY_COMMANDS_LITERAL.LTE:
- case query_1.QUERY_COMMANDS_LITERAL.GT:
- case query_1.QUERY_COMMANDS_LITERAL.GTE:
- case query_1.QUERY_COMMANDS_LITERAL.ELEM_MATCH:
- case query_1.QUERY_COMMANDS_LITERAL.EXISTS:
- case query_1.QUERY_COMMANDS_LITERAL.SIZE:
- case query_1.QUERY_COMMANDS_LITERAL.MOD: {
- return {
- [query.fieldName]: {
- [$op]: common_1.encodeInternalDataType(query.operands[0])
- }
- };
- }
- case query_1.QUERY_COMMANDS_LITERAL.IN:
- case query_1.QUERY_COMMANDS_LITERAL.NIN:
- case query_1.QUERY_COMMANDS_LITERAL.ALL: {
- return {
- [query.fieldName]: {
- [$op]: common_1.encodeInternalDataType(query.operands)
- }
- };
- }
- case query_1.QUERY_COMMANDS_LITERAL.GEO_NEAR: {
- const options = query.operands[0];
- return {
- [query.fieldName]: {
- $nearSphere: {
- $geometry: options.geometry.toJSON(),
- $maxDistance: options.maxDistance,
- $minDistance: options.minDistance
- }
- }
- };
- }
- case query_1.QUERY_COMMANDS_LITERAL.GEO_WITHIN: {
- const options = query.operands[0];
- if (options.centerSphere) {
- validate_1.Validate.isCentersPhere(options.centerSphere);
- const centerSphere = options.centerSphere;
- if (centerSphere[0]._internalType === symbol_1.SYMBOL_GEO_POINT) {
- return {
- [query.fieldName]: {
- $geoWithin: {
- $centerSphere: [centerSphere[0].toJSON().coordinates, centerSphere[1]]
- }
- }
- };
- }
- return {
- [query.fieldName]: {
- $geoWithin: {
- $centerSphere: options.centerSphere
- }
- }
- };
- }
- return {
- [query.fieldName]: {
- $geoWithin: {
- $geometry: options.geometry.toJSON()
- }
- }
- };
- }
- case query_1.QUERY_COMMANDS_LITERAL.GEO_INTERSECTS: {
- const options = query.operands[0];
- return {
- [query.fieldName]: {
- $geoIntersects: {
- $geometry: options.geometry.toJSON()
- }
- }
- };
- }
- default: {
- return {
- [query.fieldName]: {
- [$op]: common_1.encodeInternalDataType(query.operands[0])
- }
- };
- }
- }
- }
- encodeQueryObject(query) {
- const flattened = common_1.flattenQueryObject(query);
- for (const key in flattened) {
- const val = flattened[key];
- if (logic_1.isLogicCommand(val)) {
- flattened[key] = val._setFieldName(key);
- const condition = this.encodeLogicCommand(flattened[key]);
- this.mergeConditionAfterEncode(flattened, condition, key);
- }
- else if (query_1.isComparisonCommand(val)) {
- flattened[key] = val._setFieldName(key);
- const condition = this.encodeComparisonCommand(flattened[key]);
- this.mergeConditionAfterEncode(flattened, condition, key);
- }
- else if (common_1.isConversionRequired(val)) {
- flattened[key] = common_1.encodeInternalDataType(val);
- }
- }
- return flattened;
- }
- mergeConditionAfterEncode(query, condition, key) {
- if (!condition[key]) {
- delete query[key];
- }
- for (const conditionKey in condition) {
- if (query[conditionKey]) {
- if (type_1.isArray(query[conditionKey])) {
- query[conditionKey] = query[conditionKey].concat(condition[conditionKey]);
- }
- else if (type_1.isObject(query[conditionKey])) {
- if (type_1.isObject(condition[conditionKey])) {
- Object.assign(query, condition);
- }
- else {
- console.warn(`unmergable condition, query is object but condition is ${type_1.getType(condition)}, can only overwrite`, condition, key);
- query[conditionKey] = condition[conditionKey];
- }
- }
- else {
- console.warn(`to-merge query is of type ${type_1.getType(query)}, can only overwrite`, query, condition, key);
- query[conditionKey] = condition[conditionKey];
- }
- }
- else {
- query[conditionKey] = condition[conditionKey];
- }
- }
- }
- }
|