grapher/lib/query/query.js

172 lines
4.2 KiB
JavaScript
Raw Normal View History

2016-09-14 16:04:08 +03:00
import createGraph from './lib/createGraph.js';
import recursiveFetch from './lib/recursiveFetch.js';
import applyFilterFunction from './lib/applyFilterFunction.js';
2016-09-21 18:33:50 +03:00
import hypernova from './hypernova/hypernova.js';
2016-09-14 16:04:08 +03:00
export default class Query {
constructor(collection, body, params = {}) {
2016-09-14 16:04:08 +03:00
this.collection = collection;
this.body = body;
this.subscriptionHandle = null;
this._params = params;
}
clone(newParams) {
return new Query(
this.collection,
_.clone(this.body),
_.extend({}, this.params, newParams)
);
2016-09-14 16:04:08 +03:00
}
get name() {
return `exposure_${this.collection._name}`;
}
get params() {
return this._params;
}
get props() {
const body = applyFilterFunction(this.body, this.params);
return {
filters: body.$filters,
options: body.$options
}
}
2016-09-28 18:30:12 +03:00
/**
* Subscribe
*
* @param callback
* @returns {null|any|*}
*/
subscribe(callback) {
2016-09-14 16:04:08 +03:00
if (!Meteor.isClient) {
throw new Meteor.Error('not-allowed', 'You cannot subscribe from server');
}
this.subscriptionHandle = Meteor.subscribe(
this.name,
applyFilterFunction(this.body, this.params),
callback
2016-09-14 16:04:08 +03:00
);
return this.subscriptionHandle;
}
2016-09-28 18:30:12 +03:00
/**
* Unsubscribe if an existing subscription exists
*/
2016-09-14 16:04:08 +03:00
unsubscribe() {
if (!Meteor.isClient) {
throw new Meteor.Error('not-allowed', 'You cannot subscribe/unsubscribe from server');
2016-09-14 16:04:08 +03:00
}
if (this.subscriptionHandle) {
this.subscriptionHandle.stop();
}
2016-09-16 19:22:12 +03:00
this.subscriptionHandle = null;
2016-09-14 16:04:08 +03:00
}
2016-09-28 18:30:12 +03:00
/**
* Retrieves the data.
* @param callbackOrOptions
* @returns {*}
*/
fetch(callbackOrOptions) {
2016-09-14 16:04:08 +03:00
if (Meteor.isClient) {
if (!this.subscriptionHandle) {
return this._fetchAsClientMethod(callbackOrOptions)
2016-09-14 16:04:08 +03:00
} else {
return this._fetchAsClientReactive(callbackOrOptions);
2016-09-14 16:04:08 +03:00
}
} else {
return this._fetchAsServer(callbackOrOptions);
2016-09-14 16:04:08 +03:00
}
}
/**
* @param args
* @returns {*}
*/
fetchOne(...args) {
return _.first(this.fetch(...args));
}
2016-09-28 18:30:12 +03:00
/**
* Gets the count of matching elements.
* @param callback
* @returns {any}
*/
getCount(callback) {
if (Meteor.isClient) {
if (!callback) {
throw new Meteor.Error('not-allowed', 'You are on client so you must either provide a callback to get the count.');
}
return Meteor.call(this.name + '.count', applyFilterFunction(this.body, this.params), callback);
}
return this.collection.find(this.body.$filters || {}, {}).count();
}
2016-09-28 18:30:12 +03:00
/**
* Merges the params with previous params.
*
* @param data
* @returns {Query}
*/
2016-09-14 16:04:08 +03:00
setParams(data) {
_.extend(this._params, data);
return this;
2016-09-14 16:04:08 +03:00
}
/**
* Fetching non-reactive queries
* @param callback
* @private
*/
_fetchAsClientMethod(callback) {
if (!callback) {
throw new Meteor.Error('not-allowed', 'You are on client so you must either provide a callback to get the data or subscribe first.');
}
Meteor.call(this.name, applyFilterFunction(this.body, this.params), callback);
}
/**
* Fetching when we've got an active publication
*
* @param options
* @returns {*}
* @private
*/
_fetchAsClientReactive(options = {}) {
let body = applyFilterFunction(this.body, this.params);
if (!options.allowSkip && body.$options && body.$options.skip) {
delete body.$options.skip;
}
return recursiveFetch(
createGraph(this.collection, body)
);
}
/**
* Fetching from the server-side
*
* @param options
* @private
*/
_fetchAsServer(options = {}) {
const node = createGraph(
this.collection,
applyFilterFunction(this.body, this.params)
);
return hypernova(node, options.userId);
}
2016-09-14 16:04:08 +03:00
}