| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| 'use strict'; |
| |
| const qModule = require('./q'); |
| const QueryOperator = qModule.QueryOperator; |
| const QueryAssignment = qModule.QueryAssignment; |
| |
| /** |
| * Provides utility methods for obtaining a caching keys based on the specifics of the Mapper methods. |
| * @ignore |
| */ |
| class Cache { |
| /** |
| * Gets an iterator of keys to uniquely identify a document shape for a select query. |
| * @param {Array<String>} docKeys |
| * @param {Object} doc |
| * @param {{fields, limit, orderBy}} docInfo |
| * @returns {Iterator} |
| */ |
| static *getSelectKey(docKeys, doc, docInfo) { |
| yield* Cache._yieldKeyAndOperators(docKeys, doc); |
| |
| yield* Cache._getSelectDocInfo(docInfo); |
| } |
| /** |
| * Gets an iterator of keys to uniquely identify a shape for a select all query. |
| * @param {{fields, limit, orderBy}} docInfo |
| * @returns {Iterator} |
| */ |
| static *getSelectAllKey(docInfo) { |
| yield 'root'; |
| |
| yield* Cache._getSelectDocInfo(docInfo); |
| } |
| |
| /** |
| * Gets the parts of the key for a select query related to the docInfo. |
| * @param {{fields, limit, orderBy}} docInfo |
| * @private |
| */ |
| static *_getSelectDocInfo(docInfo) { |
| if (docInfo) { |
| if (docInfo.fields && docInfo.fields.length > 0) { |
| // Use a separator from properties |
| yield '|f|'; |
| yield* docInfo.fields; |
| } |
| |
| if (typeof docInfo.limit === 'number') { |
| yield '|l|'; |
| } |
| |
| if (docInfo.orderBy) { |
| yield '|o|'; |
| |
| // orderBy is uses property names as keys and 'asc'/'desc' as values |
| const keys = Object.keys(docInfo.orderBy); |
| for (let i = 0; i < keys.length; i++) { |
| const key = keys[i]; |
| yield key; |
| yield docInfo.orderBy[key]; |
| } |
| } |
| } |
| } |
| |
| /** |
| * Gets an iterator of keys to uniquely identify a document shape for an insert query. |
| * @param {Array<String>} docKeys |
| * @param {{ifNotExists, ttl, fields}} docInfo |
| * @returns {Iterator} |
| */ |
| static *getInsertKey(docKeys, docInfo) { |
| // No operator supported on INSERT values |
| yield* docKeys; |
| |
| if (docInfo) { |
| if (docInfo.fields && docInfo.fields.length > 0) { |
| // Use a separator from properties |
| yield '|f|'; |
| yield* docInfo.fields; |
| } |
| |
| if (typeof docInfo.ttl === 'number') { |
| yield '|t|'; |
| } |
| |
| if (docInfo.ifNotExists) { |
| yield '|e|'; |
| } |
| } |
| } |
| |
| /** |
| * Gets an iterator of keys to uniquely identify a document shape for an UPDATE query. |
| * @param {Array<String>} docKeys |
| * @param {Object} doc |
| * @param {{ifExists, when, ttl, fields}} docInfo |
| */ |
| static *getUpdateKey(docKeys, doc, docInfo) { |
| yield* Cache._yieldKeyAndAllQs(docKeys, doc); |
| |
| if (docInfo) { |
| if (docInfo.fields && docInfo.fields.length > 0) { |
| // Use a separator from properties |
| yield '|f|'; |
| yield* docInfo.fields; |
| } |
| |
| if (typeof docInfo.ttl === 'number') { |
| yield '|t|'; |
| } |
| |
| if (docInfo.ifExists) { |
| yield '|e|'; |
| } |
| |
| if (docInfo.when) { |
| yield* Cache._yieldKeyAndOperators(Object.keys(docInfo.when), docInfo.when); |
| } |
| } |
| } |
| |
| /** |
| * Gets an iterator of keys to uniquely identify a document shape for a DELETE query. |
| * @param {Array<String>} docKeys |
| * @param {Object} doc |
| * @param {{ifExists, when, fields, deleteOnlyColumns}} docInfo |
| * @returns {Iterator} |
| */ |
| static *getRemoveKey(docKeys, doc, docInfo) { |
| yield* Cache._yieldKeyAndOperators(docKeys, doc); |
| |
| if (docInfo) { |
| if (docInfo.fields && docInfo.fields.length > 0) { |
| // Use a separator from properties |
| yield '|f|'; |
| yield* docInfo.fields; |
| } |
| |
| if (docInfo.ifExists) { |
| yield '|e|'; |
| } |
| |
| if (docInfo.deleteOnlyColumns) { |
| yield '|dc|'; |
| } |
| |
| if (docInfo.when) { |
| yield* Cache._yieldKeyAndOperators(Object.keys(docInfo.when), docInfo.when); |
| } |
| } |
| } |
| |
| static *_yieldKeyAndOperators(keys, obj) { |
| for (let i = 0; i < keys.length; i++) { |
| const key = keys[i]; |
| yield key; |
| yield* Cache._yieldOperators(obj[key]); |
| } |
| } |
| |
| static *_yieldOperators(value) { |
| if (value !== null && value !== undefined && value instanceof QueryOperator) { |
| yield value.key; |
| if (value.hasChildValues) { |
| yield* Cache._yieldOperators(value.value[0]); |
| yield '|/|'; |
| yield* Cache._yieldOperators(value.value[1]); |
| } |
| } |
| } |
| |
| static *_yieldKeyAndAllQs(keys, obj) { |
| for (let i = 0; i < keys.length; i++) { |
| const key = keys[i]; |
| yield key; |
| const value = obj[key]; |
| if (value !== null && value !== undefined) { |
| if (value instanceof QueryOperator) { |
| yield* Cache._yieldOperators(value); |
| } |
| else if (value instanceof QueryAssignment) { |
| yield value.sign; |
| yield value.inverted; |
| } |
| } |
| } |
| } |
| } |
| |
| module.exports = Cache; |