UNPKG

lemon-core

Version:
153 lines 6.71 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CosmosQueryService = exports.QueryService = exports.QueryBuilder = void 0; /** * `cosmos-query-service.ts` * - common service to query with pkey+sort via cosmos * * * @author Ian Kim <ian@lemoncloud.io> * @date 2023-08-16 initial version with `cosmosDB` package. * * @copyright (C) 2023 LemonCloud Co Ltd. - All Rights Reserved. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const engine_1 = require("../../engine/"); const cosmos_service_1 = require("./cosmos-service"); const NS = engine_1.$U.NS('CMQR', 'green'); // NAMESPACE TO BE PRINTED. function isComparisonCondition(c) { return 'comparator' in c; } function isBetweenCondition(c) { return 'from' in c && 'to' in c; } function isExistenceCondition(c) { return 'exists' in c; } function isStringCondition(c) { return 'operator' in c; } class QueryBuilder { buildConditionExpression(condition) { return __awaiter(this, void 0, void 0, function* () { if (isComparisonCondition(condition)) { const valueExpression = condition.value === null ? 'null' : typeof condition.value === 'number' ? condition.value : `'${condition.value}'`; return `c['${condition.key}'] ${condition.comparator} ${valueExpression}`; } if (isStringCondition(condition)) { if (condition.operator === 'begins_with') return `STARTSWITH(c['${condition.key}'], '${condition.value}')`; if (condition.operator === 'contains') return `CONTAINS(c['${condition.key}'], '${condition.value}')`; } if (isBetweenCondition(condition)) { return `c['${condition.key}'] >= ${condition.from} AND c['${condition.key}'] <= ${condition.to}`; } if (isExistenceCondition(condition)) { return condition.exists ? `IS_DEFINED(c['${condition.key}'])` : `NOT IS_DEFINED(c['${condition.key}'])`; } }); } buildQueryByConditions(conditions) { return __awaiter(this, void 0, void 0, function* () { if (conditions) { const queryParts = Object.values(conditions).map((condition) => __awaiter(this, void 0, void 0, function* () { if (condition.hasOwnProperty('or')) { const orConditions = condition.or.map((orCondition) => __awaiter(this, void 0, void 0, function* () { return yield this.buildConditionExpression(orCondition); })); return `(${(yield Promise.all(orConditions)).join(' OR ')})`; } if (condition.hasOwnProperty('not')) { const notCondition = condition.not; const notExpression = yield this.buildConditionExpression(notCondition); return `NOT (${notExpression})`; } return yield this.buildConditionExpression(condition); })); const queryString = `SELECT * FROM c WHERE ${(yield Promise.all(queryParts)).join(' AND ')}`; return queryString; } return 'SELECT * FROM c'; }); } } exports.QueryBuilder = QueryBuilder; class QueryService { // Add constructor that takes options as a parameter constructor(options) { this.options = options; } queryItems(query, limit, last) { return __awaiter(this, void 0, void 0, function* () { const { databaseName, tableName } = this.options; const { client } = yield cosmos_service_1.CosmosService.instance(); const querySpec = { query, }; // cosmos DB needs continuation token for pagination const { resources: queryResult, continuationToken } = yield client .database(databaseName) .container(tableName) .items.query(querySpec, { continuationToken: last, maxItemCount: limit }) .fetchNext(); return { queryResult, continuationToken: continuationToken || undefined, }; }); } } exports.QueryService = QueryService; class CosmosQueryService { constructor(options) { /** * say hello of identity. */ this.hello = () => `cosmos-query-service:${this.options.tableName}`; // eslint-disable-next-line prettier/prettier (0, engine_1._inf)(NS, `CosmosQueryService(${options.tableName}/${options.idName}${options.sortName ? '/' : ''}${options.sortName || ''})...`); if (!options.tableName) throw new Error('.tableName is required'); if (!options.idName) throw new Error('.idName is required'); this.options = options; // Initialize the queryService this.queryService = new QueryService(options); this.queryBuilder = new QueryBuilder(); } /** * Read items by conditions using dynamic query */ scan(limit, last, conditions) { return __awaiter(this, void 0, void 0, function* () { const queryString = yield this.queryBuilder.buildQueryByConditions(conditions); const { queryResult, continuationToken } = yield this.queryService.queryItems(queryString, limit, last); if (queryResult.length >= 0) { return { list: queryResult, total: queryResult.length, last: continuationToken, }; } else { throw new Error('error'); } }); } } exports.CosmosQueryService = CosmosQueryService; //# sourceMappingURL=cosmos-query-service.js.map