cushion 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +0 -2
- data/README.md +24 -0
- data/Rakefile +1 -0
- data/cushion.gemspec +22 -0
- data/lib/cushion.rb +60 -43
- data/test/cushion_test.rb +32 -6
- metadata +24 -9
data/.gitignore
ADDED
data/Gemfile
CHANGED
data/README.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Cushion
|
2
|
+
|
3
|
+
A HashWithIndifferentAccess with a CouchDB persistence layer.
|
4
|
+
|
5
|
+
## Synopsis
|
6
|
+
|
7
|
+
Using Cushion is as simple as this:
|
8
|
+
|
9
|
+
hash = Cushion.new('/db/document')
|
10
|
+
hash.load
|
11
|
+
hash[:foo] = 'bar'
|
12
|
+
hash.save
|
13
|
+
|
14
|
+
When the document's URI consists only of the database part (`/db`), the id will be a UUID, set by CouchDB on `.save`.
|
15
|
+
|
16
|
+
Cushion can also be inherited from, which will lead to the database name being taken from the inheriting classes name. Like this:
|
17
|
+
|
18
|
+
class MyCushion < Cushion; end
|
19
|
+
hash = MyCushion.new
|
20
|
+
hash.save
|
21
|
+
|
22
|
+
In this case a document URI doesn't have to be given explicitly (even though, it can be given). For the above example, the URI would be `/my_cushions/<UUID set by CouchDB>`.
|
23
|
+
|
24
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/cushion.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'cushion'
|
6
|
+
s.version = '0.0.4'
|
7
|
+
s.authors = ['Helge Rausch']
|
8
|
+
s.email = ['helge@rausch.io']
|
9
|
+
s.homepage = 'https://github.com/tsujigiri/cushion'
|
10
|
+
s.summary = %q{A Hash with CouchDB persistence}
|
11
|
+
s.description = %q{A Hash with indifferent access and CouchDB persistence layer}
|
12
|
+
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
|
17
|
+
s.add_development_dependency 'test-unit'
|
18
|
+
s.add_development_dependency 'shoulda'
|
19
|
+
s.add_development_dependency 'ruby-debug19'
|
20
|
+
s.add_runtime_dependency 'active_support'
|
21
|
+
s.require_paths = ['lib']
|
22
|
+
end
|
data/lib/cushion.rb
CHANGED
@@ -13,33 +13,39 @@ class Cushion < HashWithIndifferentAccess
|
|
13
13
|
uri = args.shift
|
14
14
|
end
|
15
15
|
if uri.nil?
|
16
|
-
if self.class.ancestors.include?(Cushion)
|
16
|
+
if self.class.ancestors[1..-1].include?(Cushion)
|
17
17
|
uri = '/' << self.class.name.underscore.pluralize
|
18
18
|
else
|
19
19
|
raise "No database URI given"
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
document_location uri
|
23
23
|
data = args.shift
|
24
24
|
super(data, &block)
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
return @
|
29
|
-
uri =~ /(http:\/\/)?(
|
27
|
+
def document_location uri = nil
|
28
|
+
return @document_location unless uri
|
29
|
+
uri =~ /(http:\/\/)?([^:\/\?]+)?(:([0-9]+))?\/(\w+)(\/(\w+))?/
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
self.class.server [ $2 || 'localhost', $4 ? $4.to_i : 5984 ]
|
32
|
+
@document_location = {}
|
33
|
+
@document_location[:database] = $5
|
34
|
+
@id = $7
|
35
|
+
@document_location[:uri] = "/#{@document_location[:database]}/#{@id}" if @id
|
36
|
+
end
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
38
|
+
def self.create_database uri
|
39
|
+
put(uri) unless get(uri)['db_name']
|
40
|
+
database_created true
|
37
41
|
end
|
38
42
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
+
def self.database_created true_or_false = nil
|
44
|
+
if [ true, false ].include?(true_or_false)
|
45
|
+
@database_created = true_or_false
|
46
|
+
else
|
47
|
+
@database_created
|
48
|
+
end
|
43
49
|
end
|
44
50
|
|
45
51
|
def revision
|
@@ -51,46 +57,57 @@ class Cushion < HashWithIndifferentAccess
|
|
51
57
|
end
|
52
58
|
|
53
59
|
def load
|
54
|
-
replace(get)
|
60
|
+
replace(self.class.get(document_location[:uri]))
|
55
61
|
end
|
56
62
|
|
57
63
|
def save
|
58
|
-
|
64
|
+
unless self.class.database_created
|
65
|
+
self.class.create_database('/' << document_location[:database])
|
66
|
+
end
|
59
67
|
if @id.present?
|
60
|
-
|
68
|
+
copy = @revision ? self.merge(_rev: @revision) : self.dup
|
69
|
+
response = self.class.put(document_location[:uri], copy)
|
61
70
|
@revision = response['rev']
|
62
71
|
else
|
63
|
-
response = post('/' <<
|
72
|
+
response = self.class.post('/' << document_location[:database], self)
|
64
73
|
@id = response['id']
|
65
74
|
@revision = response['rev']
|
75
|
+
@document_location[:uri] = "/#{@document_location[:database]}/#{@id}"
|
66
76
|
end
|
77
|
+
@revision
|
67
78
|
end
|
68
79
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
def put uri = document_uri[:uri], data = nil
|
74
|
-
req = Net::HTTP::Put.new(uri)
|
75
|
-
req["content-type"] = "application/json"
|
76
|
-
req.body = data.to_json if data.present?
|
77
|
-
JSON.parse(request(req).body)
|
78
|
-
end
|
79
|
-
|
80
|
-
def post uri = document_uri[:uri], data = nil
|
81
|
-
req = Net::HTTP::Post.new(uri)
|
82
|
-
req["content-type"] = "application/json"
|
83
|
-
req.body = data.to_json if data.present?
|
84
|
-
JSON.parse(request(req).body)
|
85
|
-
end
|
86
|
-
|
87
|
-
def delete uri = document_uri[:uri]
|
88
|
-
JSON.parse(request(Net::HTTP::Delete.new(uri)).body)
|
89
|
-
end
|
90
|
-
|
91
|
-
private
|
80
|
+
class << self
|
81
|
+
def server host_and_port = nil
|
82
|
+
host_and_port.present? ? @server = host_and_port : @server
|
83
|
+
end
|
92
84
|
|
93
|
-
|
94
|
-
|
85
|
+
def get uri
|
86
|
+
JSON.parse(request(Net::HTTP::Get.new(uri)).body)
|
87
|
+
end
|
88
|
+
|
89
|
+
def put uri, data = nil
|
90
|
+
req = Net::HTTP::Put.new(uri)
|
91
|
+
req["content-type"] = "application/json"
|
92
|
+
req.body = data.to_json if data.present?
|
93
|
+
JSON.parse(request(req).body)
|
94
|
+
end
|
95
|
+
|
96
|
+
def post uri, data = nil
|
97
|
+
req = Net::HTTP::Post.new(uri)
|
98
|
+
req["content-type"] = "application/json"
|
99
|
+
req.body = data.to_json if data.present?
|
100
|
+
JSON.parse(request(req).body)
|
101
|
+
end
|
102
|
+
|
103
|
+
def delete uri
|
104
|
+
JSON.parse(request(Net::HTTP::Delete.new(uri)).body)
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def request(req)
|
110
|
+
Net::HTTP.start(*server) { |http| http.request(req) }
|
111
|
+
end
|
95
112
|
end
|
96
113
|
end
|
data/test/cushion_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler'
|
3
|
-
Bundler.require(:default, :
|
3
|
+
Bundler.require(:default, :development)
|
4
4
|
require_relative '../lib/cushion'
|
5
5
|
|
6
6
|
class CushionTest < Test::Unit::TestCase
|
@@ -11,11 +11,25 @@ class CushionTest < Test::Unit::TestCase
|
|
11
11
|
@doc = Cushion.new(@doc_uri, { foo: "bar", test: "data" })
|
12
12
|
end
|
13
13
|
|
14
|
-
should "
|
15
|
-
@doc.save
|
14
|
+
should "save a document with an explicit id" do
|
15
|
+
revision = @doc.save
|
16
16
|
doc = Cushion.new(@doc_uri)
|
17
|
+
assert_equal nil, doc[:foo]
|
17
18
|
doc.load
|
18
19
|
assert_equal "bar", doc[:foo]
|
20
|
+
assert_equal 'test_doc', @doc.id
|
21
|
+
new_revision = revision.to_i + 1
|
22
|
+
assert_match /#{new_revision}-[0-9a-f]{32}/, @doc.save
|
23
|
+
end
|
24
|
+
|
25
|
+
should "save a document without an explicit id" do
|
26
|
+
doc = FooCushion.new(foo: "bar")
|
27
|
+
assert_equal({ database: "foo_cushions" }, doc.document_location)
|
28
|
+
assert revision = doc.save
|
29
|
+
assert_match /\A\/foo_cushions\/[0-9a-f]{32}\Z/, doc.document_location[:uri]
|
30
|
+
assert id = doc.id
|
31
|
+
new_revision = revision.to_i + 1
|
32
|
+
assert_match /#{new_revision}-[0-9a-f]{32}/, doc.save
|
19
33
|
end
|
20
34
|
|
21
35
|
should "convert to JSON like a hash" do
|
@@ -23,13 +37,25 @@ class CushionTest < Test::Unit::TestCase
|
|
23
37
|
end
|
24
38
|
|
25
39
|
should "find the important parts in the given uri" do
|
26
|
-
@doc.
|
27
|
-
assert_equal "foo", @doc.
|
40
|
+
@doc.document_location "/foo"
|
41
|
+
assert_equal "foo", @doc.document_location[:database]
|
42
|
+
assert_equal [ 'localhost', 5984 ], @doc.class.server
|
43
|
+
@doc.document_location "http://example.com/foo"
|
44
|
+
assert_equal "foo", @doc.document_location[:database]
|
45
|
+
assert_equal [ 'example.com', 5984 ], @doc.class.server
|
46
|
+
@doc.document_location "http://example.com:1234/foo"
|
47
|
+
assert_equal "foo", @doc.document_location[:database]
|
48
|
+
assert_equal [ 'example.com', 1234 ], @doc.class.server
|
49
|
+
@doc.document_location "/foo/bar"
|
50
|
+
assert_equal "foo", @doc.document_location[:database]
|
51
|
+
assert_equal "/foo/bar", @doc.document_location[:uri]
|
52
|
+
assert_equal [ 'localhost', 5984 ], @doc.class.server
|
53
|
+
assert_equal 'bar', @doc.id
|
28
54
|
end
|
29
55
|
|
30
56
|
should "take the database name from the class name when inherited" do
|
31
57
|
foo = FooCushion.new
|
32
|
-
assert_equal "foo_cushions", foo.
|
58
|
+
assert_equal "foo_cushions", foo.document_location[:database]
|
33
59
|
end
|
34
60
|
end
|
35
61
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cushion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: test-unit
|
16
|
-
requirement: &
|
16
|
+
requirement: &11099760 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *11099760
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: shoulda
|
27
|
-
requirement: &
|
27
|
+
requirement: &11099020 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,21 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *11099020
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: ruby-debug19
|
38
|
+
requirement: &11098400 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *11098400
|
36
47
|
- !ruby/object:Gem::Dependency
|
37
48
|
name: active_support
|
38
|
-
requirement: &
|
49
|
+
requirement: &11097680 !ruby/object:Gem::Requirement
|
39
50
|
none: false
|
40
51
|
requirements:
|
41
52
|
- - ! '>='
|
@@ -43,7 +54,7 @@ dependencies:
|
|
43
54
|
version: '0'
|
44
55
|
type: :runtime
|
45
56
|
prerelease: false
|
46
|
-
version_requirements: *
|
57
|
+
version_requirements: *11097680
|
47
58
|
description: A Hash with indifferent access and CouchDB persistence layer
|
48
59
|
email:
|
49
60
|
- helge@rausch.io
|
@@ -51,7 +62,11 @@ executables: []
|
|
51
62
|
extensions: []
|
52
63
|
extra_rdoc_files: []
|
53
64
|
files:
|
65
|
+
- .gitignore
|
54
66
|
- Gemfile
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- cushion.gemspec
|
55
70
|
- lib/cushion.rb
|
56
71
|
- test/cushion_test.rb
|
57
72
|
homepage: https://github.com/tsujigiri/cushion
|
@@ -74,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
89
|
version: '0'
|
75
90
|
requirements: []
|
76
91
|
rubyforge_project:
|
77
|
-
rubygems_version: 1.8.
|
92
|
+
rubygems_version: 1.8.10
|
78
93
|
signing_key:
|
79
94
|
specification_version: 3
|
80
95
|
summary: A Hash with CouchDB persistence
|