From 480614cdc4bcf596794a9ebfb5f887e5eb3207fd Mon Sep 17 00:00:00 2001 From: Berislav Date: Mon, 24 Sep 2018 11:44:35 -0700 Subject: [PATCH] Scoped query PoC --- lib/namedQuery/namedQuery.client.js | 1 + lib/query/lib/applyProps.js | 0 lib/query/lib/createGraph.js | 16 ++++++++++++++++ lib/query/lib/recursiveCompose.js | 23 +++++++++++++++++++++-- lib/query/lib/recursiveFetch.js | 5 +++++ 5 files changed, 43 insertions(+), 2 deletions(-) mode change 100644 => 100755 lib/query/lib/applyProps.js mode change 100644 => 100755 lib/query/lib/createGraph.js mode change 100644 => 100755 lib/query/lib/recursiveCompose.js diff --git a/lib/namedQuery/namedQuery.client.js b/lib/namedQuery/namedQuery.client.js index 180ec73..bf402f6 100755 --- a/lib/namedQuery/namedQuery.client.js +++ b/lib/namedQuery/namedQuery.client.js @@ -184,6 +184,7 @@ export default class extends Base { createGraph(this.collection, body), undefined, { scoped: this.options.scoped, + queryScoped: true, subscriptionHandle: this.subscriptionHandle, }); } diff --git a/lib/query/lib/applyProps.js b/lib/query/lib/applyProps.js old mode 100644 new mode 100755 diff --git a/lib/query/lib/createGraph.js b/lib/query/lib/createGraph.js old mode 100644 new mode 100755 index c00cf4d..dc2d660 --- a/lib/query/lib/createGraph.js +++ b/lib/query/lib/createGraph.js @@ -99,6 +99,22 @@ export function addFieldNode(body, fieldName, root) { } } +/** + * Returns namespace for node when using query path scoping. + * + * @param node + * @returns {String} + */ +export function getNodeNamespace(node) { + const parts = []; + let n = node; + while (n) { + parts.push(n.collection._name); + n = n.parent; + } + return parts.reverse().join('_'); +} + /** * @param collection * @param body diff --git a/lib/query/lib/recursiveCompose.js b/lib/query/lib/recursiveCompose.js old mode 100644 new mode 100755 index 7b787fe..a12d84f --- a/lib/query/lib/recursiveCompose.js +++ b/lib/query/lib/recursiveCompose.js @@ -1,4 +1,19 @@ import applyProps from './applyProps.js'; +import {getNodeNamespace} from './createGraph'; + +function patchCursor(cursor, ns) { + const originalObserve = cursor.observe; + cursor.observe = function (callbacks) { + const newCallbacks = {}; + if (callbacks.added) { + newCallbacks.added = doc => { + doc[`__query_path_${ns}`] = ns; + callbacks.added(doc); + }; + } + originalObserve.call(cursor, newCallbacks); + }; +} function compose(node, userId) { return { @@ -18,7 +33,9 @@ function compose(node, userId) { }); } - return accessor.find(filters, options, userId); + const cursor = accessor.find(filters, options, userId); + patchCursor(cursor, getNodeNamespace(node)); + return cursor; } }, @@ -31,7 +48,9 @@ export default (node, userId, config = {bypassFirewalls: false}) => { find() { let {filters, options} = applyProps(node); - return node.collection.find(filters, options, userId); + const cursor = node.collection.find(filters, options, userId); + patchCursor(cursor, getNodeNamespace(node)); + return cursor; }, children: _.map(node.collectionNodes, n => { diff --git a/lib/query/lib/recursiveFetch.js b/lib/query/lib/recursiveFetch.js index ce38832..d02933a 100755 --- a/lib/query/lib/recursiveFetch.js +++ b/lib/query/lib/recursiveFetch.js @@ -1,6 +1,7 @@ import applyProps from './applyProps.js'; import { assembleMetadata, removeLinkStorages, storeOneResults } from './prepareForDelivery'; import prepareForDelivery from './prepareForDelivery'; +import {getNodeNamespace} from './createGraph'; /** * This is always run client side to build the data graph out of client-side collections. @@ -16,6 +17,10 @@ function fetch(node, parentObject, fetchOptions = {}) { if (fetchOptions.scoped && fetchOptions.subscriptionHandle) { _.extend(filters, fetchOptions.subscriptionHandle.scopeQuery()); } + // does not make sense without scoped parameter + if (fetchOptions.scoped && fetchOptions.queryScoped) { + _.extend(filters, {[`__query_path_${getNodeNamespace(node)}`]: {$exists: true}}); + } let results = [];