lemon-core
Version:
Lemon Serverless Micro-Service Platform
142 lines • 6.59 kB
JavaScript
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());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DynamoQueryService = void 0;
/**
* `dynamo-query-service.ts`
* - common service to query with pkey+sort via dynamo
*
*
* @author Steve Jung <steve@lemoncloud.io>
* @date 2019-11-6 initial version with `dynamodb` package.
*
* @copyright (C) 2019 LemonCloud Co Ltd. - All Rights Reserved.
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const engine_1 = require("../../engine/");
const dynamo_service_1 = require("./dynamo-service");
const NS = engine_1.$U.NS('DYQR', 'green'); // NAMESPACE TO BE PRINTED.
/** ****************************************************************************************************************
* Service Main
** ****************************************************************************************************************/
const query_1 = __importDefault(require("../../lib/dynamo/query"));
const serializer_1 = __importDefault(require("../../lib/dynamo/serializer"));
/**
* class: `DynamoQueryService`
* - support simple query like range search.
*/
class DynamoQueryService {
constructor(options) {
/**
* say hello of identity.
*/
this.hello = () => `dynamo-query-service:${this.options.tableName}`;
// eslint-disable-next-line prettier/prettier
(0, engine_1._inf)(NS, `DynamoQueryService(${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;
}
queryAll(pkey, limit, isDesc) {
return __awaiter(this, void 0, void 0, function* () {
return this.queryRangeBy(pkey, -1, -1, limit, null, isDesc);
});
}
queryRange(pkey, from, to, limit, last) {
return __awaiter(this, void 0, void 0, function* () {
return this.queryRangeBy(pkey, from, to, limit, last, false);
});
}
/**
* query by range of sort-key.
* NOTE - `dynamodb`의 일부 코드를 이용하여, 간단버전으로 지원함.
*/
queryRangeBy(pkey, from, to, limit, last, isDesc) {
return __awaiter(this, void 0, void 0, function* () {
(0, engine_1._log)(NS, `queryRangeBy(${pkey}, ${from}, ${to})...`);
const { sortName } = this.options;
const payload = this.buildQuery(pkey, from, to, limit, last, isDesc);
//! get instance of dynamodoc, and execute query().
const { dynamodoc } = dynamo_service_1.DynamoService.instance();
const res = yield dynamodoc.query(payload).promise();
if (res) {
// _log(NS, `> query[${pkey}].res =`, $U.json(res)); // `startKey`
const items = res.Items || [];
const count = res.Count;
const scannedCount = res.ScannedCount;
const $lek = res.LastEvaluatedKey || {};
const last = engine_1.$U.N($lek[sortName], 0);
(0, engine_1._log)(NS, `> query[${pkey}].items.len =`, items.length);
(0, engine_1._log)(NS, `> query[${pkey}].count =`, count);
(0, engine_1._log)(NS, `> query[${pkey}].scannedCount =`, scannedCount);
(0, engine_1._log)(NS, `> query[${pkey}].lastKey =`, last);
//! prepare result-set
const result = {
list: items,
count,
last,
};
return result;
}
//! avoid null exception
return { list: [] };
});
}
/**
* query by range of sort-key.
* NOTE - `dynamodb`의 일부 코드를 이용하여, 간단버전으로 지원함.
*/
buildQuery(pkey, from, to, limit, last, isDesc) {
(0, engine_1._log)(NS, `buildQuery(${pkey}, ${from}, ${to})...`);
//! load table information..
const { tableName, idName, sortName, idType, sortType } = this.options;
const query = new query_1.default(pkey, {
schema: {
hashKey: idName,
rangeKey: sortName,
},
tableName: () => tableName,
}, serializer_1.default);
// _log(NS, '> query =', query);
//* build query with builder.
if (sortName) {
const keyCondition = query.where(sortName);
from !== -1 && to !== -1 ? keyCondition.between(from, to) : keyCondition.gte(0);
}
isDesc ? query.descending() : query.ascending();
if (limit !== undefined)
query.limit(limit);
query.addKeyCondition(query.buildKey());
if (last)
query.startKey(pkey, last);
//TODO - replace '@' prefix of properties.
const payload = query.buildRequest();
const filter = (N) => Object.keys(N).reduce((O, key) => {
const val = N[key];
key = key.startsWith('#@') ? '#_' + key.substring(2) : key;
key = key.startsWith(':@') ? ':_' + key.substring(2) : key;
O[key] = val;
return O;
}, {});
payload.ExpressionAttributeNames = filter(payload.ExpressionAttributeNames);
payload.ExpressionAttributeValues = filter(payload.ExpressionAttributeValues);
payload.KeyConditionExpression = payload.KeyConditionExpression.replace(/([\#\:])@/g, '$1_');
(0, engine_1._log)(NS, `> payload[${pkey}] =`, engine_1.$U.json(payload));
return payload;
}
}
exports.DynamoQueryService = DynamoQueryService;
//# sourceMappingURL=dynamo-query-service.js.map
;