couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dam...@apache.org
Subject svn commit: r684092 - in /incubator/couchdb/trunk: share/www/script/couch.js share/www/script/couch_tests.js src/couchdb/couch_httpd.erl
Date Fri, 08 Aug 2008 21:06:30 GMT
Author: damien
Date: Fri Aug  8 14:06:29 2008
New Revision: 684092

URL: http://svn.apache.org/viewvc?rev=684092&view=rev
Log:
Idempotent document creation support, new HTTP api to generate UUIDs and support in the couch.js
library for using them. Creating uuids client side ensure that document creation happens only
once, despite automatic network retries.

Modified:
    incubator/couchdb/trunk/share/www/script/couch.js
    incubator/couchdb/trunk/share/www/script/couch_tests.js
    incubator/couchdb/trunk/src/couchdb/couch_httpd.erl

Modified: incubator/couchdb/trunk/share/www/script/couch.js
URL: http://svn.apache.org/viewvc/incubator/couchdb/trunk/share/www/script/couch.js?rev=684092&r1=684091&r2=684092&view=diff
==============================================================================
--- incubator/couchdb/trunk/share/www/script/couch.js [utf-8] (original)
+++ incubator/couchdb/trunk/share/www/script/couch.js [utf-8] Fri Aug  8 14:06:29 2008
@@ -42,18 +42,14 @@
   this.save = function(doc, options) {
     var req;
     if (doc._id == undefined)
-      req = request("POST", this.uri + encodeOptions(options), {
-        body: JSON.stringify(doc)
-      });
-    else
-      req = request("PUT", this.uri  + encodeURIComponent(doc._id) + encodeOptions(options),
{
-        body: JSON.stringify(doc)
-      });
+      doc._id = CouchDB.newUuids(1)[0];
+
+    req = request("PUT", this.uri  + encodeURIComponent(doc._id) + encodeOptions(options),
{
+      body: JSON.stringify(doc)
+    });
     var result = JSON.parse(req.responseText);
     if (req.status != 201)
       throw result;
-    // set the _id and _rev members on the input object, for caller convenience.
-    doc._id = result.id;
     doc._rev = result.rev;
     return result;
   }
@@ -91,6 +87,18 @@
   }
   
   this.bulkSave = function(docs, options) {
+    // first prepoulate the UUIDs for new documents
+    var newCount = 0
+    for (var i=0; i<docs.length; i++) {
+      if (docs[i]._id == undefined)
+        newCount++;
+    }
+    var newUuids = CouchDB.newUuids(docs.length);
+    var newCount = 0
+    for (var i=0; i<docs.length; i++) {
+      if (docs[i]._id == undefined)
+        docs[i]._id = newUuids.pop();
+    }
     var req = request("POST", this.uri + "_bulk_docs" + encodeOptions(options), {
       body: JSON.stringify({"docs": docs})
     });
@@ -98,7 +106,6 @@
     if (req.status != 201)
       throw result;
     for (var i = 0; i < docs.length; i++) {
-        docs[i]._id = result.new_revs[i].id;
         docs[i]._rev = result.new_revs[i].rev;
     }
     return result;
@@ -232,3 +239,26 @@
   req.send(options.body || "");
   return req;
 }
+
+CouchDB.uuids_cache = [];
+
+CouchDB.newUuids = function(n) {
+    if (CouchDB.uuids_cache.length >= n) {
+      var uuids = CouchDB.uuids_cache.slice(CouchDB.uuids_cache.length - n);
+      if(CouchDB.uuids_cache.length - n == 0) {
+        CouchDB.uuids_cache = [];
+      } else {
+        CouchDB.uuids_cache =
+            CouchDB.uuids_cache.slice(0, CouchDB.uuids_cache.length - n);
+      }
+      return uuids;
+    } else {
+      var req = CouchDB.request("POST", "/_uuids?count=" + (100 + n));
+      var result = JSON.parse(req.responseText);
+      if (req.status != 200)
+        throw result;
+      CouchDB.uuids_cache =
+          CouchDB.uuids_cache.concat(result.uuids.slice(0, 100));
+      return result.uuids.slice(100);
+    }
+  }

Modified: incubator/couchdb/trunk/share/www/script/couch_tests.js
URL: http://svn.apache.org/viewvc/incubator/couchdb/trunk/share/www/script/couch_tests.js?rev=684092&r1=684091&r2=684092&view=diff
==============================================================================
--- incubator/couchdb/trunk/share/www/script/couch_tests.js [utf-8] (original)
+++ incubator/couchdb/trunk/share/www/script/couch_tests.js [utf-8] Fri Aug  8 14:06:29 2008
@@ -194,6 +194,42 @@
     }
   },
 
+  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 xhr = CouchDB.request("POST", "/_uuids");
+    T(xhr.status == 200);
+    var result = JSON.parse(xhr.responseText);
+    T(result.uuids.length == 1);
+    var first = result.uuids[0];
+
+    // a single UUID with an explicit count
+    xhr = CouchDB.request("POST", "/_uuids?count=1");
+    T(xhr.status == 200);
+    result = JSON.parse(xhr.responseText);
+    T(result.uuids.length == 1);
+    var second = result.uuids[0];
+    T(first != second);
+
+    // no collisions with 1,000 UUIDs
+    xhr = CouchDB.request("POST", "/_uuids?count=1000");
+    T(xhr.status == 200);
+    result = JSON.parse(xhr.responseText);
+    T( result.uuids.length == 1000 );
+    var seen = {};
+    for(var i in result.uuids) {
+      var id = result.uuids[i];
+      T(seen[id] === undefined);
+      seen[id] = 1;
+    }
+    
+    // check our library
+  },
+  
   bulk_docs: function(debug) {
     var db = new CouchDB("test_suite_db");
     db.deleteDb();

Modified: incubator/couchdb/trunk/src/couchdb/couch_httpd.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/trunk/src/couchdb/couch_httpd.erl?rev=684092&r1=684091&r2=684092&view=diff
==============================================================================
--- incubator/couchdb/trunk/src/couchdb/couch_httpd.erl (original)
+++ incubator/couchdb/trunk/src/couchdb/couch_httpd.erl Fri Aug  8 14:06:29 2008
@@ -97,6 +97,8 @@
             handle_replicate_request(Req, Method);
         "/_restart" ->
             handle_restart_request(Req, Method);
+        "/_uuids" ->
+            handle_uuids_request(Req, Method);
         "/_utils" ->
             {ok, Req:respond({301, [
                 {"Location", "/_utils/"}
@@ -148,6 +150,17 @@
 handle_restart_request(_Req, _Method) ->
     throw({method_not_allowed, "POST"}).
 
+handle_uuids_request(Req, 'POST') ->
+    Count = list_to_integer(proplists:get_value("count", Req:parse_qs(), "1")),
+    % generate the uuids
+    UUIDs = [ couch_util:new_uuid() || _ <- 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, "POST"}).
+
+
 % Database request handlers
 
 handle_db_request(Req, Method, {Path}) ->



Mime
View raw message