summaryrefslogtreecommitdiff
path: root/share
diff options
context:
space:
mode:
authorJohn Christopher Anderson <jchris@apache.org>2009-07-20 04:11:36 +0000
committerJohn Christopher Anderson <jchris@apache.org>2009-07-20 04:11:36 +0000
commit46bf4b727f0fae37b017f194983122c50d3f34e5 (patch)
tree658da02543e8f53388d6ea427afa3e6265d5254d /share
parentc3175ec3b2809a553cd0f45bfa39ca573676f842 (diff)
Initial checkin of _changes filters. The prime weak-spot for this approach is that it maintains an OS-process per connected filtered _changes consumer. I'm pretty sure we'll be able to work around this without changing the API, but it'll involve a lot of OS-process bookkeeping. Those enhancements should generally improve show & list performance as well. Punting on them for now, first wanted to get _changes filters implemented so people could give feedback.
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@795687 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'share')
-rw-r--r--share/Makefile.am1
-rw-r--r--share/server/filter.js25
-rw-r--r--share/server/loop.js3
-rw-r--r--share/www/script/test/changes.js62
4 files changed, 90 insertions, 1 deletions
diff --git a/share/Makefile.am b/share/Makefile.am
index 99a05426..d1cdb457 100644
--- a/share/Makefile.am
+++ b/share/Makefile.am
@@ -13,6 +13,7 @@
JS_FILE = server/main.js
JS_FILE_COMPONENTS = \
+ server/filter.js \
server/render.js \
server/state.js \
server/util.js \
diff --git a/share/server/filter.js b/share/server/filter.js
new file mode 100644
index 00000000..23536db0
--- /dev/null
+++ b/share/server/filter.js
@@ -0,0 +1,25 @@
+// Licensed 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.
+
+var Filter = {
+ filter : function(docs, req, userCtx) {
+ var results = [];
+ try {
+ for (var i=0; i < docs.length; i++) {
+ results.push((funs[0](docs[i], req, userCtx) && true) || false);
+ };
+ respond([true, results]);
+ } catch (error) {
+ respond(error);
+ }
+ }
+};
diff --git a/share/server/loop.js b/share/server/loop.js
index d65ff02b..af656121 100644
--- a/share/server/loop.js
+++ b/share/server/loop.js
@@ -41,7 +41,8 @@ var dispatch = {
"rereduce" : Views.rereduce,
"validate" : Validate.validate,
"show" : Render.show,
- "list" : Render.list
+ "list" : Render.list,
+ "filter" : Filter.filter
};
while (line = eval(readline())) {
diff --git a/share/www/script/test/changes.js b/share/www/script/test/changes.js
index f2d33c17..f5a3e149 100644
--- a/share/www/script/test/changes.js
+++ b/share/www/script/test/changes.js
@@ -110,4 +110,66 @@ couchTests.changes = function(debug) {
T(str.charAt(str.length - 1) == "\n")
T(str.charAt(str.length - 2) == "\n")
}
+
+ // test the filtered changes
+ var ddoc = {
+ _id : "_design/changes_filter",
+ "filters" : {
+ "bop" : "function(doc, req, userCtx) { return (doc.bop);}",
+ "dynamic" : stringFun(function(doc, req, userCtx) {
+ var field = req.query.field;
+ return doc[field];
+ }),
+ "userCtx" : stringFun(function(doc, req, userCtx) {
+ return doc.user && (doc.user == userCtx.name);
+ })
+ }
+ }
+
+ db.save(ddoc);
+
+ var req = CouchDB.request("GET", "/test_suite_db/_changes?filter=changes_filter/bop");
+ var resp = JSON.parse(req.responseText);
+ T(resp.results.length == 0);
+
+ db.save({"bop" : "foom"});
+
+ var req = CouchDB.request("GET", "/test_suite_db/_changes?filter=changes_filter/bop");
+ var resp = JSON.parse(req.responseText);
+ T(resp.results.length == 1);
+
+ req = CouchDB.request("GET", "/test_suite_db/_changes?filter=changes_filter/dynamic&field=woox");
+ resp = JSON.parse(req.responseText);
+ T(resp.results.length == 0);
+
+ req = CouchDB.request("GET", "/test_suite_db/_changes?filter=changes_filter/dynamic&field=bop");
+ resp = JSON.parse(req.responseText);
+ T(resp.results.length == 1);
+
+ // test for userCtx
+ run_on_modified_server(
+ [{section: "httpd",
+ key: "authentication_handler",
+ value: "{couch_httpd, special_test_authentication_handler}"},
+ {section:"httpd",
+ key: "WWW-Authenticate",
+ value: "X-Couch-Test-Auth"}],
+
+ function() {
+ var authOpts = {"headers":{"WWW-Authenticate": "X-Couch-Test-Auth Chris Anderson:mp3"}};
+
+ T(db.save({"user" : "Noah Slater"}).ok);
+ var req = CouchDB.request("GET", "/test_suite_db/_changes?filter=changes_filter/userCtx", authOpts);
+ var resp = JSON.parse(req.responseText);
+ T(resp.results.length == 0);
+
+ var docResp = db.save({"user" : "Chris Anderson"});
+ T(docResp.ok);
+ req = CouchDB.request("GET", "/test_suite_db/_changes?filter=changes_filter/userCtx", authOpts);
+ resp = JSON.parse(req.responseText);
+ T(resp.results.length == 1);
+ T(resp.results[0].id == docResp.id);
+ });
+
+ // todo implement adhoc filters...
};