Created
April 29, 2010 15:38
-
-
Save dvv/383784 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- mongodb.js.orig 2010-04-30 22:19:10.000000000 +0400 | |
+++ mongodb.js 2010-05-01 16:03:49.000000000 +0400 | |
@@ -85,7 +85,6 @@ | |
if(typeof query === "string"){ | |
query = parseQuery(query); | |
} | |
- var grabOneColumn, deleteId; | |
var options = {}; | |
query.forEach(function(term){ | |
@@ -109,41 +108,38 @@ | |
}); | |
} else if (term.name == "select") { | |
- var parameters = options.fields = term.parameters; | |
- if(parameters.length === 1){ | |
- grabOneColumn = parameters[0]; | |
- }else if(parameters.indexOf("_id") > -1){ | |
- deleteId = true; | |
- } | |
- } else if (term.name == "slice") { | |
- directives.start = term.parameters[0]; | |
- directives.end = term.parameters[1]; | |
+ options.fields = term.parameters; | |
} | |
} | |
// TODO: add support for alternate comparators, sorting, etc. | |
}); | |
- if(directives.start || directives.end){ | |
- var totalCountPromise = callAsync(collection.count, [search]); | |
- } | |
+ var totalCountPromise = callAsync(collection.count, [search]); | |
if(directives.start){ | |
options.skip = directives.start; | |
} | |
- if(directives.end){ | |
- options.limit = directives.end - (directives.start || 0); | |
+ if(directives.end !== undefined){ | |
+ options.limit = directives.end - (directives.start || 0) + 1; | |
} | |
return callAsync(collection.find, [search, options]).then(function(results){ | |
var resultsPromise = convertNodeAsyncFunction(results.toArray).call(results); | |
if(totalCountPromise){ | |
return resultsPromise.then(function(results){ | |
return totalCountPromise.then(function(totalCount){ | |
- if(grabOneColumn){ | |
- for(var i = 0, l = results.length; i < l; i++){ | |
- results[i] = results[i][grabOneColumn]; | |
+ var n = results.length; | |
+ var fields = options.fields; | |
+ if (fields) { | |
+ // single column requested? -> reduce result objects to single values | |
+ if (fields.length === 1) { | |
+ var column = fields[0]; | |
+ for(var i = 0; i < n; i++){ | |
+ results[i] = results[i][column]; | |
+ } | |
} | |
- } | |
- if(deleteId){ | |
- for(var i = 0, l = results.length; i < l; i++){ | |
- delete results[i]._id; | |
+ // mongo _always_ includes _id | |
+ if (fields.indexOf("_id") == -1) { | |
+ for(var i = 0; i < n; i++){ | |
+ delete results[i]._id; | |
+ } | |
} | |
} | |
results.totalCount = totalCount; | |
--- rest-store.js.orig 2010-04-30 22:19:07.000000000 +0400 | |
+++ rest-store.js 2010-05-01 16:05:33.751266903 +0400 | |
@@ -63,18 +63,28 @@ | |
else if(!METHOD_HAS_BODY[method]){ | |
if(method === "get" && request.pathInfo.substring(request.pathInfo.length - 1) === "/"){ | |
// handle the range header | |
- var range = request.headers.range || "=0-"; | |
- var parts = range.match(/=(\w+)-(\w+)?/); | |
- metadata.start = parseFloat(parts[1], 10); | |
- metadata.end = parseFloat(parts[2] || Infinity, 10); | |
- // queries are not decoded, the info needs to be retained for parsing | |
- responseValue = store.query(path, metadata); | |
- var count = responseValue.totalCount || responseValue.length || 0; | |
- var end = Math.min(metadata.end, metadata.start + count - 1); | |
- if (count) { | |
- headers["content-range"] = "items " + metadata.start + '-' + end + '/' + count; | |
+ var range = request.headers.range || "items=0-"; | |
+ var parts = range.replace('items=','').split('-'); | |
+ // syntaxically invalid "Range:" just results in 0-Infinity | |
+ metadata.start = +parts[0] || undefined; | |
+ metadata.end = +parts[1] || undefined; | |
+ // DVV: shortcut evaluation of range that would result in empty set | |
+ if (metadata.end < metadata.start) { | |
+ responseValue = []; | |
+ } else { | |
+ // queries are not decoded, the info needs to be retained for parsing | |
+ // TODO: limit the range by a configurable number | |
+ responseValue = store.query(path, metadata); | |
} | |
- status = (metadata.start === 0 && count -1 === end) ? 200 : 206; | |
+ // DVV: we have to wait for promise for counts to be set (e.g., mongo) | |
+ when(responseValue, function(responseValue){ | |
+ var count = responseValue.totalCount || responseValue.length || 0; | |
+ metadata.start = metadata.start || 0; | |
+ metadata.end = metadata.start + (responseValue.length || 0) - 1; | |
+ // DVV: query should always respond with Content-Range: even if no actual results is returned | |
+ headers["content-range"] = "items " + metadata.start + '-' + metadata.end + '/' + (count || '*'); | |
+ status = (metadata.start === 0 && count -1 === metadata.end) ? 200 : 206; | |
+ }); | |
} | |
else{ | |
// call the store with just the path |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment