UNPKG

pebblebed

Version:

Simplified interactions with Google Datastore for NodeJS

186 lines 9.37 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.createHashFromQuery = exports.createDataStringFromQuery = exports.createDatastoreQuery = void 0; const extractAncestorPaths_1 = require("../utility/extractAncestorPaths"); const augmentEntitiesWithIdProperties_1 = require("../utility/augmentEntitiesWithIdProperties"); const convertToType_1 = require("../utility/convertToType"); const Core_1 = require("../Core"); const pickOutEntityFromResults_1 = require("../utility/pickOutEntityFromResults"); const Messaging_1 = require("../Messaging"); const deserializeJsonProperties_1 = require("../utility/deserializeJsonProperties"); const crypto = require("crypto"); function createDatastoreQuery(model, namespace) { const idProp = model.entityIdProperty; const kind = model.entityKind; const hasIdProp = model.entityHasIdProperty; const type = hasIdProp ? model.entitySchema[model.entityIdProperty].type : null; const schema = model.entitySchema; const ns = namespace !== Core_1.UNSET_NAMESPACE ? namespace : (Core_1.default.Instance.namespace !== Core_1.UNSET_NAMESPACE ? Core_1.default.Instance.namespace : null); const dsQuery = (ns != null && ns !== Core_1.UNSET_NAMESPACE) ? Core_1.default.Instance.dsModule.createQuery(ns, model.entityKind) : Core_1.default.Instance.dsModule.createQuery(model.entityKind); const runQuery = dsQuery.run.bind(dsQuery); const filterQuery = dsQuery.filter.bind(dsQuery); const useCache = (model.modelOptions.neverCache || !Core_1.default.Instance.caching) ? false : Core_1.default.Instance.cacheDefaults.onQuery; const returnOnlyEntity = null; const cachingTimeSeconds = model.modelOptions.defaultCachingSeconds != null ? model.modelOptions.defaultCachingSeconds : Core_1.default.Instance.defaultCachingSeconds; return Object.assign(dsQuery, { returnOnlyEntity, useCache, cachingTimeSeconds, enableCache(on) { this.useCache = on; return this; }, cachingSeconds(seconds) { this.cachingTimeSeconds = seconds; return this; }, first() { this.returnOnlyEntity = "FIRST"; return this; }, last() { this.returnOnlyEntity = "LAST"; return this; }, randomOne() { this.returnOnlyEntity = "RANDOM"; return this; }, filter(property, comparator, value) { if (!schema[property]) { (0, Messaging_1.throwError)(`Property "${property}" doesn't exist on entity schema for [ ${kind} ]`); } return filterQuery(property, comparator, (0, convertToType_1.default)(value, schema[property].type)); }, withAncestors(...args) { const ancestors = (0, extractAncestorPaths_1.default)(model, ...args); if (ns != null) { this.hasAncestor(Core_1.default.Instance.dsModule.key({ namespace: ns, path: [].concat.apply([], ancestors), })); } else { this.hasAncestor(Core_1.default.Instance.dsModule.key([].concat.apply([], ancestors))); } return this; }, flushQueryInCache() { return __awaiter(this, void 0, void 0, function* () { if (Core_1.default.Instance.cacheStore != null) { const hash = createHashFromQuery(this); yield Core_1.default.Instance.cacheStore.flushQueryResponse(hash, this); } else { (0, Messaging_1.warn)(`Trying to flush a query - but no Cache Store has been set on Pebblebed instance!`); } }); }, run(throwIfNotFound = false) { return __awaiter(this, void 0, void 0, function* () { let hash = null; if (Core_1.default.Instance.cacheStore != null && Core_1.default.Instance.cacheStore.cacheOnQuery && this.useCache) { hash = createHashFromQuery(this); const queryResponse = yield Core_1.default.Instance.cacheStore.getQueryResponse(hash, this); if (queryResponse != null) { cachingAugmentQueryEntitiesWithRealKeys(queryResponse); (0, deserializeJsonProperties_1.default)(queryResponse.entities, schema); if (this.returnOnlyEntity != null) { return (0, pickOutEntityFromResults_1.default)(queryResponse.entities, this.returnOnlyEntity); } return queryResponse; } } const data = yield runQuery(); if (hasIdProp && data[0].length > 0) { (0, augmentEntitiesWithIdProperties_1.default)(data[0], idProp, type, kind); } const queryResponse = { entities: data[0], info: data[1], }; if (Core_1.default.Instance.cacheStore != null && Core_1.default.Instance.cacheStore.cacheOnQuery && this.useCache && queryResponse.entities.length > 0) { if (hash == null) { hash = createHashFromQuery(this); } cachingAugmentQueryEntitiesWithSerializableKeys(queryResponse); yield Core_1.default.Instance.cacheStore.setQueryResponse(queryResponse, hash, this.cachingTimeSeconds, this); removeSerializableKeysFromEntities(queryResponse); } (0, deserializeJsonProperties_1.default)(queryResponse.entities, schema); if (queryResponse.entities.length === 0 && throwIfNotFound) { console.error(`Couldn't find any ${model.entityKind} entity(s) with specified query:\n\n${createDataStringFromQuery(this)}`); (0, Messaging_1.throwError)(`Couldn't find any ${model.entityKind} entity(s) with specified query, see server log for more detail`); } if (this.returnOnlyEntity != null) { return (0, pickOutEntityFromResults_1.default)(queryResponse.entities, this.returnOnlyEntity); } return queryResponse; }); }, }); } exports.createDatastoreQuery = createDatastoreQuery; function createDataStringFromQuery(query) { return `namespace:${query.namespace != null ? query.namespace : ""} kinds:${query.kinds.join("-KIND_JOIN-")} filters:${JSON.stringify(query.filters)} limit:${query.limitVal} offset:${query.offsetVal} orders:${query.orders.join("-ORDERS_JOIN-")} select:${query.selectVal.join("-SELECT_JOIN-")} groupBy:${query.groupByVal.join("-GROUP_BY_JOIN-")} start:${query.startVal} end:${query.endVal}`; } exports.createDataStringFromQuery = createDataStringFromQuery; function createHashFromQuery(query) { /*const dataString = `namespace:${query.namespace != null ? query.namespace : ""} kinds:${query.kinds.join("-KIND_JOIN-")} filters:${JSON.stringify(query.filters)} limit:${query.limitVal} offset:${query.offsetVal} orders:${query.orders.join("-ORDERS_JOIN-")} select:${query.selectVal.join("-SELECT_JOIN-")} groupBy:${query.groupByVal.join("-GROUP_BY_JOIN-")} start:${query.startVal} end:${query.endVal}`;*/ return crypto.createHash("sha1").update(createDataStringFromQuery(query)).digest("base64"); } exports.createHashFromQuery = createHashFromQuery; const serializableKeyName = "__pebblebed_serializable_key__"; function cachingAugmentQueryEntitiesWithSerializableKeys(queryResponse) { for (const entity of queryResponse.entities) { entity[serializableKeyName] = entity[Core_1.default.Instance.dsModule.KEY]; } } function removeSerializableKeysFromEntities(queryResponse) { for (const entity of queryResponse.entities) { delete entity[serializableKeyName]; } } function cachingAugmentQueryEntitiesWithRealKeys(queryResponse) { for (const entity of queryResponse.entities) { entity[Core_1.default.Instance.dsModule.KEY] = entity[serializableKeyName]; delete entity[serializableKeyName]; } } //# sourceMappingURL=DatastoreQuery.js.map