summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/server/main.js45
-rw-r--r--share/www/browse/database.html2
-rw-r--r--share/www/script/couch.js27
-rw-r--r--share/www/script/couch_tests.js118
4 files changed, 100 insertions, 92 deletions
diff --git a/share/server/main.js b/share/server/main.js
index 59acb02f..43660c7b 100644
--- a/share/server/main.js
+++ b/share/server/main.js
@@ -17,17 +17,16 @@ var map_results = []; // holds temporary emitted values during doc map
var sandbox = null;
emit = function(key, value) {
- map_results.push([key, value]);
- }
-
+ map_results.push([key, value]);
+}
+
sum = function(values) {
- var values_sum=0;
- for(var i in values) {
- values_sum += values[i];
- }
- return values_sum;
+ var rv = 0;
+ for (var i in values) {
+ rv += values[i];
}
-
+ return rv;
+}
try {
// if possible, use evalcx (not always available)
@@ -53,8 +52,8 @@ while (cmd = eval(readline())) {
case "add_fun":
// The second arg is a string that will compile to a function.
// and then we add it to funs array
- funs.push(safe_compile_function(cmd[1]));
- print("true");
+ funs.push(compileFunction(cmd[1]));
+ print("true");
break;
case "map_doc":
// The second arg is a document. We compute all the map functions against
@@ -97,10 +96,10 @@ while (cmd = eval(readline())) {
}
print(toJSON(buf));
break;
-
+
case "combine":
case "reduce":
- {
+ {
var keys = null;
var values = null;
var reduceFuns = cmd[1];
@@ -117,11 +116,11 @@ while (cmd = eval(readline())) {
values = cmd[2];
is_combine = true;
}
-
- for(var i in reduceFuns) {
- reduceFuns[i] = safe_compile_function(reduceFuns[i]);
+
+ for (var i in reduceFuns) {
+ reduceFuns[i] = compileFunction(reduceFuns[i]);
}
-
+
var reductions = new Array(funs.length);
for (var i = 0; i < reduceFuns.length; i++) {
try {
@@ -138,30 +137,30 @@ while (cmd = eval(readline())) {
print("[true," + toJSON(reductions) + "]");
}
break;
-
+
default:
print(toJSON({error: "query_server_error",
reason: "unknown command '" + cmd[0] + "'"}));
quit();
}
- } catch(exception) {
+ } catch (exception) {
print(toJSON(exception));
}
}
-function safe_compile_function(Src) {
+function compileFunction(source) {
try {
- var functionObject = sandbox ? evalcx(Src, sandbox) : eval(Src);
+ var functionObject = sandbox ? evalcx(source, sandbox) : eval(source);
} catch (err) {
throw {error: "compilation_error",
- reason: err.toString() + " (" + Src + ")"};
+ reason: err.toString() + " (" + source + ")"};
}
if (typeof(functionObject) == "function") {
return functionObject;
} else {
throw {error: "compilation_error",
- reason: "expression does not eval to a function. (" + Src + ")"};
+ reason: "expression does not eval to a function. (" + source + ")"};
}
}
diff --git a/share/www/browse/database.html b/share/www/browse/database.html
index c685baad..76990608 100644
--- a/share/www/browse/database.html
+++ b/share/www/browse/database.html
@@ -111,7 +111,7 @@ specific language governing permissions and limitations under the License.
<label for="viewcode_textarea">View Function</label>
</div>
<textarea id="viewcode_textarea" rows="5" cols="79" spellcheck="false" wrap="off">function(doc) {
- map(null, doc);
+ emit(null, doc);
}</textarea>
<div class="bottom">
<button class="save" type="button" disabled>Save</button>
diff --git a/share/www/script/couch.js b/share/www/script/couch.js
index d63f1eae..0b2f828c 100644
--- a/share/www/script/couch.js
+++ b/share/www/script/couch.js
@@ -94,12 +94,19 @@ function CouchDB(name) {
}
// Applies the map function to the contents of database and returns the results.
- this.query = function(mapFun, options) {
+ this.query = function(mapFun, reduceFun, options) {
+ var body = {language: "javascript"};
if (typeof(mapFun) != "string")
mapFun = mapFun.toSource ? mapFun.toSource() : "(" + mapFun.toString() + ")";
+ body.map = mapFun;
+ if (reduceFun != null) {
+ if (typeof(reduceFun) != "string")
+ reduceFun = reduceFun.toSource ? reduceFun.toSource() : "(" + reduceFun.toString() + ")";
+ body.reduce = reduceFun;
+ }
var req = request("POST", this.uri + "_temp_view" + encodeOptions(options), {
headers: {"Content-Type": "application/json"},
- body: JSON.stringify({language:"javascript",map:mapFun})
+ body: JSON.stringify(body)
});
var result = JSON.parse(req.responseText);
if (req.status != 200)
@@ -107,22 +114,6 @@ function CouchDB(name) {
return result;
}
- // Applies the map function to the contents of database and returns the results.
- this.reduce_query = function(mapFun, reduceFun, options) {
- if (typeof(mapFun) != "string")
- mapFun = mapFun.toSource ? mapFun.toSource() : "(" + mapFun.toString() + ")";
- if (typeof(reduceFun) != "string")
- reduceFun = reduceFun.toSource ? reduceFun.toSource() : "(" + reduceFun.toString() + ")";
- var req = request("POST", this.uri + "_temp_view" + encodeOptions(options), {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({language:"javascript",map:mapFun,reduce:reduceFun})
- });
- var result = JSON.parse(req.responseText);
- if (req.status != 200)
- throw result;
- return result;
- }
-
this.view = function(viewname, options) {
var req = request("GET", this.uri + "_view/" + viewname + encodeOptions(options));
if (req.status == 404)
diff --git a/share/www/script/couch_tests.js b/share/www/script/couch_tests.js
index cb8e8506..43dd6551 100644
--- a/share/www/script/couch_tests.js
+++ b/share/www/script/couch_tests.js
@@ -91,15 +91,15 @@ var tests = {
// 1 more document should now be in the result.
T(results.total_rows == 3);
T(db.info().doc_count == 6);
-
+
var reduceFunction = function(keys, values){
return sum(values);
};
-
- result = db.reduce_query(mapFunction, reduceFunction);
+
+ result = db.query(mapFunction, reduceFunction);
T(result.result == 33);
-
+
// delete a document
T(db.deleteDoc(existingDoc).ok);
@@ -218,7 +218,9 @@ var tests = {
}
// do the query again, but with descending output
- results = db.query(function(doc){ emit(doc.integer, null) }, {descending:true});
+ results = db.query(function(doc){ emit(doc.integer, null) }, null, {
+ descending: true
+ });
T(results.total_rows == numDocsToCreate);
@@ -227,7 +229,7 @@ var tests = {
T(results.rows[numDocsToCreate-1-i].key==i);
}
},
-
+
reduce: function(debug) {
var db = new CouchDB("test_suite_db");
db.deleteDb();
@@ -237,26 +239,23 @@ var tests = {
var docs = makeDocs(1,numDocs + 1);
T(db.bulkSave(docs).ok);
var summate = function(N) {return (N+1)*N/2;};
-
+
var map = function (doc) {emit(doc.integer, doc.integer)};
- var reduce = function (keys, values) { return sum(values); };
- var result = db.reduce_query(map, reduce).result;
+ var reduce = function (keys, values) { return sum(values); };
+ var result = db.query(map, reduce).result;
T(result == summate(numDocs));
-
- result = db.reduce_query(map, reduce, {startkey:4,endkey:4}).result;
-
+
+ result = db.query(map, reduce, {startkey: 4, endkey: 4}).result;
T(result == 4);
-
- result = db.reduce_query(map, reduce, {startkey:4,endkey:5}).result;
-
+
+ result = db.query(map, reduce, {startkey: 4, endkey: 5}).result;
T(result == 9);
-
- result = db.reduce_query(map, reduce, {startkey:4,endkey:6}).result;
-
+
+ result = db.query(map, reduce, {startkey: 4, endkey: 6}).result;
T(result == 15);
-
+
for(var i=1; i<numDocs/2; i+=30) {
- result = db.reduce_query(map, reduce, {startkey:i,endkey:numDocs-i}).result;
+ result = db.query(map, reduce, {startkey: i, endkey: numDocs - i}).result;
T(result == summate(numDocs-i) - summate(i-1));
}
},
@@ -458,24 +457,24 @@ var tests = {
T(db.view("test/single_doc").total_rows == 1)
restartServer();
}
-
-
+
+
var summate = function(N) {return (N+1)*N/2;};
var result = db.view("test/summate").result;
T(result == summate(numDocs));
-
+
result = db.view("test/summate", {startkey:4,endkey:4}).result;
-
+
T(result == 4);
-
+
result = db.view("test/summate", {startkey:4,endkey:5}).result;
-
+
T(result == 9);
-
+
result =db.view("test/summate", {startkey:4,endkey:6}).result;
-
+
T(result == 15);
-
+
for(var i=1; i<numDocs/2; i+=30) {
result = db.view("test/summate", {startkey:i,endkey:numDocs-i}).result;
T(result == summate(numDocs-i) - summate(i-1));
@@ -488,7 +487,7 @@ var tests = {
restartServer();
T(db.open(designDoc._id) == null);
T(db.view("test/no_docs") == null);
-
+
},
view_collation: function(debug) {
@@ -555,7 +554,7 @@ var tests = {
}
// everything has collated correctly. Now to check the descending output
- rows = db.query(queryFun, {descending:true}).rows
+ rows = db.query(queryFun, null, {descending: true}).rows
for (i=0; i<values.length; i++) {
T(equals(rows[i].key, values[values.length - 1 -i]))
}
@@ -563,7 +562,7 @@ var tests = {
// now check the key query args
for (i=1; i<values.length; i++) {
var queryOptions = {key:values[i]}
- rows = db.query(queryFun, queryOptions).rows;
+ rows = db.query(queryFun, null, queryOptions).rows;
T(rows.length == 1 && equals(rows[0].key, values[i]))
}
},
@@ -620,7 +619,11 @@ var tests = {
// page through the view ascending and going forward
for (i = 0; i < docs.length; i += 10) {
- var queryResults = db.query(queryFun, {startkey:i, startkey_docid:i, count:10});
+ var queryResults = db.query(queryFun, null, {
+ startkey: i,
+ startkey_docid: i,
+ count: 10
+ });
T(queryResults.rows.length == 10)
T(queryResults.total_rows == docs.length)
T(queryResults.offset == i)
@@ -632,8 +635,11 @@ var tests = {
// page through the view ascending and going backward
for (i = docs.length - 1; i >= 0; i -= 10) {
- var queryResults = db.query(queryFun, {startkey:i, startkey_docid:i,
- count:-10})
+ var queryResults = db.query(queryFun, null, {
+ startkey: i,
+ startkey_docid: i,
+ count:-10
+ });
T(queryResults.rows.length == 10)
T(queryResults.total_rows == docs.length)
T(queryResults.offset == i - 9)
@@ -645,8 +651,12 @@ var tests = {
// page through the view descending and going forward
for (i = docs.length - 1; i >= 0; i -= 10) {
- var queryResults = db.query(queryFun, {startkey:i, startkey_docid:i,
- descending:true, count:10})
+ var queryResults = db.query(queryFun, null, {
+ startkey: i,
+ startkey_docid: i,
+ descending: true,
+ count: 10
+ });
T(queryResults.rows.length == 10)
T(queryResults.total_rows == docs.length)
T(queryResults.offset == docs.length - i - 1)
@@ -658,8 +668,12 @@ var tests = {
// page through the view descending and going backward
for (i = 0; i < docs.length; i += 10) {
- var queryResults = db.query(queryFun, {startkey:i, startkey_docid:i,
- descending:true, count:-10});
+ var queryResults = db.query(queryFun, null, {
+ startkey: i,
+ startkey_docid: i,
+ descending: true,
+ count:-10
+ });
T(queryResults.rows.length == 10)
T(queryResults.total_rows == docs.length)
T(queryResults.offset == docs.length - i - 10)
@@ -668,11 +682,15 @@ var tests = {
T(queryResults.rows[j].key == i + 9 - j);
}
}
-
+
// ignore decending=false. CouchDB should just ignore that.
for (i = 0; i < docs.length; i += 10) {
- var queryResults = db.query(queryFun, {startkey:i, startkey_docid:i,
- descending:false, count:10});
+ var queryResults = db.query(queryFun, null, {
+ startkey: i,
+ startkey_docid: i,
+ descending: false,
+ count: 10
+ });
T(queryResults.rows.length == 10)
T(queryResults.total_rows == docs.length)
T(queryResults.offset == i)
@@ -928,7 +946,7 @@ var tests = {
var docs = makeDocs(0, 10);
var saveResult = db.bulkSave(docs);
T(saveResult.ok);
-
+
var binAttDoc = {
_id:"bin_doc",
@@ -941,28 +959,28 @@ var tests = {
}
T(db.save(binAttDoc).ok);
-
+
var originalsize = db.info().disk_size;
-
+
for(var i in docs) {
db.deleteDoc(docs[i]);
}
var deletesize = db.info().disk_size;
T(deletesize > originalsize);
-
+
var xhr = CouchDB.request("POST", "/test_suite_db/_compact");
T(xhr.status == 202);
//compaction isn't instantaneous, loop until done
while(db.info().compact_running) {};
-
-
+
+
var xhr = CouchDB.request("GET", "/test_suite_db/bin_doc/foo.txt");
T(xhr.responseText == "This is a base64 encoded text")
T(xhr.getResponseHeader("content-type") == "text/plain")
-
+
var compactedsize = db.info().disk_size;
-
+
T(deletesize > originalsize);
}
};