diff --git a/lib/couch_rest.rb b/lib/couch_rest.rb index 66c7bfe..dd31e67 100644 --- a/lib/couch_rest.rb +++ b/lib/couch_rest.rb @@ -1,7 +1,8 @@ class CouchRest - attr_accessor :uri - def initialize server = 'http://localhost:5984' + attr_accessor :uri, :uuid_batch_count + def initialize server = 'http://localhost:5984', uuid_batch_count = 1000 @uri = server + @uuid_batch_count = uuid_batch_count end # ensure that a database exists @@ -29,13 +30,13 @@ class CouchRest end def database name - CouchRest::Database.new(@uri, name) + CouchRest::Database.new(self, name) end # creates the database if it doesn't exist def database! name create_db(path) rescue nil - CouchRest::Database.new(@uri, name) + database name end # get the welcome message @@ -43,17 +44,25 @@ class CouchRest CouchRest.get "#{@uri}/" end - # restart the couchdb instance - def restart! - CouchRest.post "#{@uri}/_restart" - end - # create a database def create_db name CouchRest.put "#{@uri}/#{name}" database name end + # restart the couchdb instance + def restart! + CouchRest.post "#{@uri}/_restart" + end + + def next_uuid count = @uuid_batch_count + @uuids ||= [] + if @uuids.empty? + @uuids = CouchRest.post("#{@uri}/_uuids?count=#{count}")["uuids"] + end + @uuids.pop + end + class << self def put uri, doc = nil payload = doc.to_json if doc diff --git a/lib/database.rb b/lib/database.rb index 7482fd8..bb7bfbc 100644 --- a/lib/database.rb +++ b/lib/database.rb @@ -3,10 +3,11 @@ require "base64" class CouchRest class Database - attr_accessor :host, :name - def initialize host, name + attr_accessor :server, :host, :name + def initialize server, name @name = name - @host = host + @server = server + @host = server.uri @root = "#{host}/#{name}" end @@ -62,13 +63,18 @@ class CouchRest end if doc['_id'] slug = CGI.escape(doc['_id']) - CouchRest.put "#{@root}/#{slug}", doc else - CouchRest.post "#{@root}", doc + slug = doc['_id'] = @server.next_uuid end + CouchRest.put "#{@root}/#{slug}", doc end def bulk_save docs + ids, noids = docs.partition{|d|d['_id']} + uuid_count = [noids.length, @server.uuid_batch_count].max + noids.each do |doc| + doc['_id'] = @server.next_uuid(uuid_count) + end CouchRest.post "#{@root}/_bulk_docs", {:docs => docs} end @@ -80,7 +86,9 @@ class CouchRest def delete! CouchRest.delete @root end + private + def encode_attachments attachments attachments.each do |k,v| next if v['stub'] @@ -88,6 +96,7 @@ class CouchRest end attachments end + def base64 data Base64.encode64(data).gsub(/\s/,'') end diff --git a/spec/couchrest_spec.rb b/spec/couchrest_spec.rb index af69cdc..bfa8e0a 100644 --- a/spec/couchrest_spec.rb +++ b/spec/couchrest_spec.rb @@ -26,10 +26,12 @@ describe CouchRest do end end - describe "description" do - it "should restart" do - @cr.restart! - end + it "should restart" do + @cr.restart! + end + + it "should provide one-time access to uuids" do + @cr.next_uuid.should_not be_nil end describe "initializing a database" do diff --git a/spec/database_spec.rb b/spec/database_spec.rb index 83163a5..a12fe07 100644 --- a/spec/database_spec.rb +++ b/spec/database_spec.rb @@ -138,6 +138,16 @@ describe CouchRest::Database do end end + it "should use uuids when ids aren't provided" do + @db.server.stub!(:next_uuid).and_return('asdf6sgadkfhgsdfusdf') + + docs = [{'key' => 'value'}, {'_id' => 'totally-uniq'}] + id_docs = [{'key' => 'value', '_id' => 'asdf6sgadkfhgsdfusdf'}, {'_id' => 'totally-uniq'}] + CouchRest.should_receive(:post).with("http://localhost:5984/couchrest-test/_bulk_docs", {:docs => id_docs}) + + @db.bulk_save(docs) + end + it "should add them with uniq ids" do rs = @db.bulk_save([ {"_id" => "oneB", "wild" => "and random"}, @@ -179,7 +189,7 @@ describe CouchRest::Database do end end - describe "POST (new document without an id)" do + describe "new document without an id" do it "should start empty" do @db.documents["total_rows"].should == 0 end @@ -188,6 +198,11 @@ describe CouchRest::Database do r2 = @db.get(r['id']) r2["lemons"].should == "from texas" end + it "should use PUT with UUIDs" do + CouchRest.should_receive(:put) + r = @db.save({'just' => ['another document']}) + end + end describe "PUT document with attachment" do