On Fri, Oct 30, 2009 at 08:37:36PM -0400, Adam Kocoloski wrote:
> The response format is a slightly awkward Array -- I believe the first  
> revision is the winning one.

This is definitely not true. For example, I can get the database into a
state where there are three conflicting versions, and the winning version
is the middle one returned by open_revs=all

$ curl http://127.0.0.1:5984/conflict_test/test?conflicts=true
{"_id":"test","_rev":"10-ca7d1f8bc31d20ad4898e4024547c4c6","hello":"baz","_conflicts":["9-9b4928288c4fc3087833549752bdcdc3","9-2438fa9601119c8fe2c0b2f4a688f65f"]}
$ curl http://127.0.0.1:5984/conflict_test/test?open_revs=all
[{"ok":{"_id":"test","_rev":"9-2438fa9601119c8fe2c0b2f4a688f65f","hello":"bar"}},
{"ok":{"_id":"test","_rev":"10-ca7d1f8bc31d20ad4898e4024547c4c6","hello":"baz"}},
{"ok":{"_id":"test","_rev":"9-9b4928288c4fc3087833549752bdcdc3","hello":"foo"}}]

Code to do this is attached.

Regards,

Brian.
require 'rubygems'
require 'restclient'
require 'json'
DB="http://127.0.0.1:5984/conflict_test";

# Write multiple documents as all_or_nothing, can introduce conflicts
def writem(docs)
  JSON.parse(RestClient.post("#{DB}/_bulk_docs", {
    "all_or_nothing" => true,
    "docs" => docs,
  }.to_json))
end

# Write one document, return the rev
def write1(doc, id=nil, rev=nil)
  doc['_id'] = id if id
  doc['_rev'] = rev if rev
  writem([doc]).first['rev']
end

# Read a document, return *all* revs
def read1(id)
  retries = 0
  loop do
    # FIXME: escape id
    res = [JSON.parse(RestClient.get("#{DB}/#{id}?conflicts=true"))]
    if revs = res.first.delete('_conflicts')
      begin
        revs.each do |rev|
          res << JSON.parse(RestClient.get("#{DB}/#{id}?rev=#{rev}"))
        end
      rescue
        retries += 1
        raise if retries >= 5
        next
      end
    end
    return res
  end
end

# Create DB
RestClient.delete DB rescue nil
RestClient.put DB, {}.to_json

# Write a document
rev1 = nil
8.times do
  rev1 = write1({"hello"=>"xxx"},"test",rev1)
  p read1("test")
end
p read1("test")

# Make three 9- conflicting revisions
write1({"hello"=>"foo"},"test",rev1)
write1({"hello"=>"bar"},"test",rev1)
rev1 = write1({"hello"=>"xxx"},"test",rev1)

# Replace one of these with a 10- revision
write1({"hello"=>"baz"},"test",rev1)

puts "Read with conflicts=true:"
puts RestClient.get("#{DB}/test?conflicts=true")

puts "Read with open_revs=all:"
puts RestClient.get("#{DB}/test?open_revs=all")

Reply via email to