From 256b3c426e0b23f594dfaa502a90f8ef8a753ac5 Mon Sep 17 00:00:00 2001 From: Garret Alfert Date: Sun, 27 Oct 2013 22:09:47 +0100 Subject: [PATCH] Use ETags as version in directory listings --- lib/remote_storage/riak.rb | 12 +++++++++--- spec/directories_spec.rb | 37 ++++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/lib/remote_storage/riak.rb b/lib/remote_storage/riak.rb index 3ca5b62..768de46 100644 --- a/lib/remote_storage/riak.rb +++ b/lib/remote_storage/riak.rb @@ -241,8 +241,9 @@ module RemoteStorage sub_directories(user, directory).each do |entry| directory_name = entry["name"].split("/").last timestamp = entry["timestamp"].to_i + etag = entry["etag"] - listing.merge!({ "#{directory_name}/" => timestamp }) + listing.merge!({ "#{directory_name}/" => etag }) end directory_entries(user, directory).each do |entry| @@ -252,8 +253,9 @@ module RemoteStorage else DateTime.rfc2822(entry["last_modified"]).to_time.to_i end + etag = entry["etag"] - listing.merge!({ entry_name => timestamp }) + listing.merge!({ entry_name => etag }) end listing @@ -270,10 +272,12 @@ module RemoteStorage key_name = keys.join(':'); last_modified_date = v.values[0]['metadata']['X-Riak-Last-Modified']; timestamp = v.values[0]['metadata']['X-Riak-Meta']['X-Riak-Meta-Timestamp']; + etag = v.values[0]['metadata']['X-Riak-VTag']; return [{ name: key_name, last_modified: last_modified_date, timestamp: timestamp, + etag: etag }]; } EOH @@ -289,10 +293,12 @@ module RemoteStorage function(v){ keys = v.key.split(':'); key_name = keys[keys.length-1]; - timestamp = v.values[0]['data'] + timestamp = v.values[0]['data']; + etag = v.values[0]['metadata']['X-Riak-VTag']; return [{ name: key_name, timestamp: timestamp, + etag: etag }]; } EOH diff --git a/spec/directories_spec.rb b/spec/directories_spec.rb index 704f33b..1e5f656 100644 --- a/spec/directories_spec.rb +++ b/spec/directories_spec.rb @@ -19,17 +19,18 @@ describe "Directories" do put "/jimmy/tasks/http%3A%2F%2F5apps.com", "prettify design" end - it "lists the objects with a timestamp of the last modification" do + it "lists the objects with their version" do get "/jimmy/tasks/" last_response.status.must_equal 200 last_response.content_type.must_equal "application/json" + foo = data_bucket.get("jimmy:tasks:foo") + content = JSON.parse(last_response.body) content.must_include "http://5apps.com" content.must_include "foo" - content["foo"].must_be_kind_of Integer - content["foo"].to_s.length.must_equal 13 + content["foo"].must_equal foo.etag.gsub(/"/, "") end it "has a Last-Modifier header set" do @@ -103,12 +104,13 @@ describe "Directories" do last_response.status.must_equal 200 + home = directory_bucket.get("jimmy:tasks/home") + content = JSON.parse(last_response.body) content.must_include "foo" content.must_include "http://5apps.com" content.must_include "home/" - content["home/"].must_be_kind_of Integer - content["home/"].to_s.length.must_equal 13 + content["home/"].must_equal home.etag.gsub(/"/, "") end it "updates the ETag of the parent directory" do @@ -149,10 +151,11 @@ describe "Directories" do last_response.status.must_equal 200 + projects = directory_bucket.get("jimmy:tasks/private/projects") + content = JSON.parse(last_response.body) content.must_include "projects/" - content["projects/"].must_be_kind_of Integer - content["projects/"].to_s.length.must_equal 13 + content["projects/"].must_equal projects.etag.gsub(/"/, "") end it "updates the timestamps of the existing directory objects" do @@ -184,10 +187,11 @@ describe "Directories" do last_response.status.must_equal 200 + jaypeg = data_bucket.get("jimmy:tasks:jaypeg.jpg") + content = JSON.parse(last_response.body) content.must_include "jaypeg.jpg" - content["jaypeg.jpg"].must_be_kind_of Integer - content["jaypeg.jpg"].to_s.length.must_equal 13 + content["jaypeg.jpg"].must_equal jaypeg.etag.gsub(/"/, "") end end @@ -204,10 +208,11 @@ describe "Directories" do last_response.status.must_equal 200 + jaypeg = data_bucket.get("jimmy:tasks:jaypeg.jpg") + content = JSON.parse(last_response.body) content.must_include "jaypeg.jpg" - content["jaypeg.jpg"].must_be_kind_of Integer - content["jaypeg.jpg"].to_s.length.must_equal 13 + content["jaypeg.jpg"].must_equal jaypeg.etag.gsub(/"/, "") end end end @@ -223,10 +228,11 @@ describe "Directories" do last_response.status.must_equal 200 + laundry = data_bucket.get("jimmy:tasks/home:laundry") + content = JSON.parse(last_response.body) content.must_include "laundry" - content["laundry"].must_be_kind_of Integer - content["laundry"].to_s.length.must_equal 13 + content["laundry"].must_equal laundry.etag.gsub(/"/, "") end end @@ -300,12 +306,13 @@ describe "Directories" do last_response.status.must_equal 200 + tasks = directory_bucket.get("jimmy:tasks") + content = JSON.parse(last_response.body) content.must_include "root-1" content.must_include "root-2" content.must_include "tasks/" - content["tasks/"].must_be_kind_of Integer - content["tasks/"].to_s.length.must_equal 13 + content["tasks/"].must_equal tasks.etag.gsub(/"/, "") end it "has an ETag header set" do