This looks good. I'll see about checking this in later.
Anyone know if Micheal need to sign a ICLA or anything? On Jul 24, 2008, at 1:15 AM, Michael Hendricks wrote:
Because a POST request to create a new document is not idempotent, PUT requests should be used when possible. Unfortunately, generating a sufficiently random document identifier from JavaScript is slightly difficult. To make the process easier, this patch exposes CouchDB's functionality for generating UUIDs so that it's accessible with an HTTP request. This patch implements a new CouchDB URI _uuids which responds to GET requests with a JSON object something like this: { "uuids" : [ "405f021c2bdfee1cb0ead93b0864c2d2", "512d8fecc3f9a421a902f0815e5cbc3f", "fc5be6230fcffd061af50169ecb1647f" ], } The number of UUIDs returned is specified with a "count" query parameter. The count parameter defaults to 1. Signed-off-by: Michael Hendricks <[EMAIL PROTECTED]> --- share/www/script/couch.js | 11 +++++++++++share/www/script/couch_tests.js | 33 ++++++++++++++++++++++++++++++ +++src/couchdb/couch_httpd.erl | 18 ++++++++++++++++++ 3 files changed, 62 insertions(+), 0 deletions(-) diff --git a/share/www/script/couch.js b/share/www/script/couch.js index 38c9cf3..fc6f8b0 100644 --- a/share/www/script/couch.js +++ b/share/www/script/couch.js @@ -160,6 +160,17 @@ function CouchDB(name) { return result; } + this.uuids = function(count) { + var uri = "/_uuids"; + if (count) uri = uri + "?count=" + count; + var req = request("GET", uri); + var result = JSON.parse(req.responseText); + if (req.status != 200) + throw result; + return result; + } + + // Convert a options object to an url query string.// ex: {key:'value',key2:'value2'} becomes '? key="value"&key2="value2"'function encodeOptions(options) {diff --git a/share/www/script/couch_tests.js b/share/www/script/ couch_tests.jsindex 852f9cf..711e3c1 100644 --- a/share/www/script/couch_tests.js +++ b/share/www/script/couch_tests.js @@ -1338,6 +1338,39 @@ var tests = { T(xhr.getResponseHeader("Content-Type") == "text/plain") T(db.info().doc_count == 1); T(db.info().disk_size < deletesize); + }, + + uuids: function(debug) { + var db = new CouchDB("test_suite_db"); + db.deleteDb(); + db.createDb(); + if (debug) debugger; + + // a single UUID without an explicit count + var result = db.uuids(); + T(result.uuids.length == 1); + var first = result.uuids[0]; + + // a single UUID with an explicit count + result = db.uuids(1); + T( result.uuids.length == 1 ); + var second = result.uuids[0]; + T( first != second ); + + // no collisions with 1,000 UUIDs + result = db.uuids(1000); + T( result.uuids.length == 1000 ); + var seen = {}; + for( var i in result.uuids ) { + var id = result.uuids[i]; + if ( seen[id] ) { + seen[id]++; + T( seen[id] == 1 ); // this will always fail + } + else { + seen[id] = 1; + } + } } }; diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl index af8d9b4..d41e1ac 100644 --- a/src/couchdb/couch_httpd.erl +++ b/src/couchdb/couch_httpd.erl @@ -97,6 +97,8 @@ handle_request0(Req, DocumentRoot, Method, Path) -> handle_replicate_request(Req, Method); "/_restart" -> handle_restart_request(Req, Method); + "/_uuids" -> + handle_uuids_request(Req, Method); "/_utils" -> {ok, Req:respond({301, [ {"Location", "/_utils/"} @@ -147,6 +149,22 @@ handle_restart_request(Req, 'POST') -> handle_restart_request(_Req, _Method) -> throw({method_not_allowed, "POST"}). +handle_uuids_request(Req, 'GET') ->+ Count = list_to_integer(proplists:get_value("count", Req:parse_qs(), "1")),+ % generate the uuids + UUIDs = lists:map( + fun (_) -> couch_util:new_uuid() end, + lists:seq(1,Count) + ), + % send a JSON response + send_json(Req, {obj, [ + {"uuids", list_to_tuple(UUIDs)} + ]}); + +handle_uuids_request(_Req, _Method) -> + throw({method_not_allowed, "GET"}). + + % Database request handlers handle_db_request(Req, Method, {Path}) -> -- 1.5.6
