Return-Path: Delivered-To: apmail-incubator-couchdb-commits-archive@locus.apache.org Received: (qmail 57294 invoked from network); 8 Aug 2008 21:07:21 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 8 Aug 2008 21:07:21 -0000 Received: (qmail 34991 invoked by uid 500); 8 Aug 2008 21:07:20 -0000 Delivered-To: apmail-incubator-couchdb-commits-archive@incubator.apache.org Received: (qmail 34966 invoked by uid 500); 8 Aug 2008 21:07:20 -0000 Mailing-List: contact couchdb-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: couchdb-dev@incubator.apache.org Delivered-To: mailing list couchdb-commits@incubator.apache.org Received: (qmail 34957 invoked by uid 99); 8 Aug 2008 21:07:20 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 08 Aug 2008 14:07:20 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 08 Aug 2008 21:06:33 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id A5E13238889D; Fri, 8 Aug 2008 14:06:30 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: couchdb-commits@incubator.apache.org From: damien@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080808210630.A5E13238889D@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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= 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}) ->