From a627b9a4b0193193e8a05ae030a25c913d742ea0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jordan=20Aug=C3=A9?= Date: Tue, 7 May 2013 18:12:57 +0200 Subject: [PATCH] improved subquery support --- manifold/js/manifold-query.js | 89 ++++++++++++++++------- manifold/js/manifold.js | 133 ++++++++++++++++++++-------------- manifold/manifoldapi.py | 2 +- 3 files changed, 142 insertions(+), 82 deletions(-) diff --git a/manifold/js/manifold-query.js b/manifold/js/manifold-query.js index 7d885ae7..4d1ec0dd 100644 --- a/manifold/js/manifold-query.js +++ b/manifold/js/manifold-query.js @@ -120,13 +120,13 @@ INSERT INTO subject VALUES(field=value) if (pos != -1) { var subject = k.substr(0, pos); var field = k.substr(pos+1); - if (jQuery.inArray(this.subject, q.subqueries) == -1) { - q.subqueries[this.subject] = new ManifoldQuery(); - q.subqueries[this.subject].action = this.action; - q.subqueries[this.subject].subject = this.subject; - q.subqueries[this.subject].timestamp = this.timestamp; + if (!q.subqueries[subject]) { + q.subqueries[subject] = new ManifoldQuery(); + q.subqueries[subject].action = this.action; + q.subqueries[subject].subject = this.subject; + q.subqueries[subject].timestamp = this.timestamp; } - q.subqueries[this.subject].filters.push(Array(field, op, v)); + q.subqueries[subject].filters.push(Array(field, op, v)); } else { q.filters.push(this.filter); } @@ -138,13 +138,13 @@ INSERT INTO subject VALUES(field=value) if (pos != -1) { var subject = param.substr(0, pos); var field = param.substr(pos+1); - if (jQuery.inArray(this.subject, q.subqueries) == -1) { - q.subqueries[this.subject] = new ManifoldQuery(); - q.subqueries[this.subject].action = this.action; - q.subqueries[this.subject].subject = this.subject; - q.subqueries[this.subject].timestamp = this.timestamp; + if (!q.subqueries[subject]) { + q.subqueries[subject] = new ManifoldQuery(); + q.subqueries[subject].action = this.action; + q.subqueries[subject].subject = this.subject; + q.subqueries[subject].timestamp = this.timestamp; } - q.subqueries[this.subject].params[field] = value; + q.subqueries[subject].params[field] = value; } else { q.params[field] = value; } @@ -156,13 +156,13 @@ INSERT INTO subject VALUES(field=value) if (pos != -1) { var subject = v.substr(0, pos); var field = v.substr(pos+1); - if (jQuery.inArray(this.subject, q.subqueries) == -1) { - q.subqueries[this.subject] = new ManifoldQuery(); - q.subqueries[this.subject].action = this.action; - q.subqueries[this.subject].subject = this.subject; - q.subqueries[this.subject].timestamp = this.timestamp; + if (!q.subqueries[subject]) { + q.subqueries[subject] = new ManifoldQuery(); + q.subqueries[subject].action = this.action; + q.subqueries[subject].subject = this.subject; + q.subqueries[subject].timestamp = this.timestamp; } - q.subqueries[this.subject].fields.push(field); + q.subqueries[subject].fields.push(field); } else { q.fields.push(v); } @@ -171,14 +171,49 @@ INSERT INTO subject VALUES(field=value) } /* constructor */ - this.action = action; - this.subject = subject; - this.timestamp = timestamp; - this.filters = filters; - this.params = params; - this.fields = fields; - this.unique = unique; + if (typeof action == "undefined") + this.action = "get"; + else + this.action = action; + + if (typeof subject == "undefined") + this.subject = null; + else + this.subject = subject; + + if (typeof timestamp == "undefined") + this.timestamp = "now"; + else + this.timestamp = timestamp; + + if (typeof filters == "undefined") + this.filters = []; + else + this.filters = filters; + + if (typeof params == "undefined") + this.params = {}; + else + this.params = params; + + if (typeof fields == "undefined") + this.fields = []; + else + this.fields = fields; + + if (typeof unique == "undefined") + this.unique = false; + else + this.unique = unique; + this.query_uuid = query_uuid; - this.analyzed_query = aq; - this.subqueries = sq; + if (typeof analyzed_query == "undefined") + this.analyzed_query = null; + else + this.analyzed_query = aq; + + if (typeof subqueries == "undefined") + this.subqueries = {}; + else + this.subqueries = sq; } diff --git a/manifold/js/manifold.js b/manifold/js/manifold.js index 81c61ce4..f6c4f563 100644 --- a/manifold/js/manifold.js +++ b/manifold/js/manifold.js @@ -18,16 +18,41 @@ function debug_query (msg, query) { } /* ------------------------------------------------------------ */ -// this namespace holds functions for globally managing query objects + +/*! + * This namespace holds functions for globally managing query objects + * \Class Manifold + */ var manifold = { + /*! + * Associative array storing the set of queries active on the page + * \memberof Manifold + */ all_queries: {}, + /*! + * Insert a query in the global hash table associating uuids to queries. + * If the query has no been analyzed yet, let's do it. + * \fn insert_query(query) + * \memberof Manifold + * \param ManifoldQuery query Query to be added + */ insert_query : function (query) { - manifold.all_queries[query.query_uuid]=query; + if (query.analyzed_query == null) { + query.analyze_subqueries(); + } + manifold.all_queries[query.query_uuid]=query; }, + + /*! + * Returns the query associated to a UUID + * \fn find_query(query_uuid) + * \memberof Manifold + * \param string query_uuid The UUID of the query to be returned + */ find_query : function (query_uuid) { - return manifold.all_queries[query_uuid]; + return manifold.all_queries[query_uuid]; }, // trigger a query asynchroneously @@ -38,68 +63,68 @@ var manifold = { // Executes all async. queries // input queries are specified as a list of {'query_uuid': , 'id': } asynchroneous_exec : function (query_publish_dom_tuples) { - // start spinners - - // in case the spin stuff was not loaded, let's make sure we proceed to the exit - try { - if (manifold.asynchroneous_debug) - messages.debug("Turning on spin with " + jQuery(".need-spin").length + " matches for .need-spin"); - jQuery('.need-spin').spin(spin_presets); - } catch (err) { messages.debug("Cannot turn on spins " + err); } + // start spinners + + // in case the spin stuff was not loaded, let's make sure we proceed to the exit + try { + if (manifold.asynchroneous_debug) + messages.debug("Turning on spin with " + jQuery(".need-spin").length + " matches for .need-spin"); + jQuery('.need-spin').spin(spin_presets); + } catch (err) { messages.debug("Cannot turn on spins " + err); } - // We use js function closure to be able to pass the query (array) to the - // callback function used when data is received - var success_closure = function(query, publish_uuid, domid) { - return function(data, textStatus) {manifold.asynchroneous_success(data, query, publish_uuid, domid);}}; - - // Loop through input array, and use publish_uuid to publish back results - jQuery.each(query_publish_dom_tuples, function(index, tuple) { - var query=manifold.find_query(tuple.query_uuid); - var query_json=JSON.stringify (query); - var publish_uuid=tuple.publish_uuid; - // by default we publish using the same uuid of course - if (publish_uuid==undefined) publish_uuid=query.query_uuid; - if (manifold.asynchroneous_debug) { - messages.debug("sending POST on " + manifold.proxy_url + " to be published on " + publish_uuid); - messages.debug("... ctd... with actual query= " + query.__repr()); - } - // not quite sure what happens if we send a string directly, as POST data is named.. - // this gets reconstructed on the proxy side with ManifoldQuery.fill_from_POST - jQuery.post(manifold.proxy_url, {'json':query_json} , success_closure(query, publish_uuid, tuple.domid)); - }) - }, + // We use js function closure to be able to pass the query (array) to the + // callback function used when data is received + var success_closure = function(query, publish_uuid, domid) { + return function(data, textStatus) {manifold.asynchroneous_success(data, query, publish_uuid, domid);}}; + + // Loop through input array, and use publish_uuid to publish back results + jQuery.each(query_publish_dom_tuples, function(index, tuple) { + var query=manifold.find_query(tuple.query_uuid); + var query_json=JSON.stringify (query); + var publish_uuid=tuple.publish_uuid; + // by default we publish using the same uuid of course + if (publish_uuid==undefined) publish_uuid=query.query_uuid; + if (manifold.asynchroneous_debug) { + messages.debug("sending POST on " + manifold.proxy_url + " to be published on " + publish_uuid); + messages.debug("... ctd... with actual query= " + query.__repr()); + } + // not quite sure what happens if we send a string directly, as POST data is named.. + // this gets reconstructed on the proxy side with ManifoldQuery.fill_from_POST + jQuery.post(manifold.proxy_url, {'json':query_json} , success_closure(query, publish_uuid, tuple.domid)); + }) + }, // if set domid allows the result to be directed to just one plugin // most of the time publish_uuid will be query.query_uuid // however in some cases we wish to publish the results under a different uuid // e.g. an updater wants to publish its results as if from the original (get) query asynchroneous_success : function (data, query, publish_uuid, domid) { - // xxx should have a nicer declaration of that enum in sync with the python code somehow - if (data.code == 1) { - alert("Your session has expired, please log in again"); - window.location="/logout/"; - return; - } else if (data.code != 0) { - messages.error("Error received from manifold backend at " + MANIFOLD_URL + " [" + data.output + "]"); - // publish error code and text message on a separate channel for whoever is interested - jQuery.publish("/results/" + publish_uuid + "/failed", [data.code, data.output] ); - return; - } - // once everything is checked we can use the 'value' part of the manifoldresult - var value=data.value; - if (value) { + // xxx should have a nicer declaration of that enum in sync with the python code somehow + if (data.code == 2) { // ERROR + alert("Your session has expired, please log in again"); + window.location="/logout/"; + return; + } + if (data.code == 1) { // WARNING + messages.error("Some errors have been received from the manifold backend at " + MANIFOLD_URL + " [" + data.description + "]"); + // publish error code and text message on a separate channel for whoever is interested + jQuery.publish("/results/" + publish_uuid + "/failed", [data.code, data.description] ); + } + // once everything is checked we can use the 'value' part of the manifoldresult + var value=data.value; + if (value) { if (!!domid) { - /* Directly inform the requestor */ - if (manifold.asynchroneous_debug) messages.debug("directing results to " + domid); - jQuery('#' + domid).trigger('results', [value]); + /* Directly inform the requestor */ + if (manifold.asynchroneous_debug) messages.debug("directing results to " + domid); + jQuery('#' + domid).trigger('results', [value]); } else { - /* Publish an update announce */ - var channel="/results/" + publish_uuid + "/changed"; - if (manifold.asynchroneous_debug) messages.debug("publishing results on " + channel); - jQuery.publish(channel, [value, query]); + /* Publish an update announce */ + var channel="/results/" + publish_uuid + "/changed"; + if (manifold.asynchroneous_debug) messages.debug("publishing results on " + channel); + jQuery.publish(channel, [value, query]); } - } + } }, }; // manifold object diff --git a/manifold/manifoldapi.py b/manifold/manifoldapi.py index 1826ba84..12da1033 100644 --- a/manifold/manifoldapi.py +++ b/manifold/manifoldapi.py @@ -44,7 +44,7 @@ class ManifoldAPI: # XXX jordan : we need to wrap it into a ResultValue structure # XXX this is not good until we merge both repos if result['code'] != 2: - return ManifoldResult(code=result['code'], value=result['result']) + return ManifoldResult(code=result['code'], value=result['value']) else: return ManifoldResult(code=result['code'], output=result['description']) else: -- 2.43.0