cushion 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile CHANGED
@@ -1,4 +1,2 @@
1
1
  source 'http://rubygems.org'
2
-
3
2
  gemspec
4
-
@@ -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
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -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
@@ -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
- document_uri uri
22
+ document_location uri
23
23
  data = args.shift
24
24
  super(data, &block)
25
25
  end
26
26
 
27
- def document_uri uri = nil
28
- return @document_uri unless uri
29
- uri =~ /(http:\/\/)?(\w+)?:?([0-9]+)?\/(\w+)(\/(\w+))?/
27
+ def document_location uri = nil
28
+ return @document_location unless uri
29
+ uri =~ /(http:\/\/)?([^:\/\?]+)?(:([0-9]+))?\/(\w+)(\/(\w+))?/
30
30
 
31
- @document_uri = { host: $2 || 'localhost',
32
- port: $3 || 5984 }
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
- @document_uri[:database] = $4
35
- @id = $6
36
- @document_uri[:uri] = "/#{@document_uri[:database]}/#{@id}" if @id
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 create_database
40
- database_uri = "/#{document_uri[:database]}"
41
- put(database_uri) unless get(database_uri)['db_name']
42
- @database_created = true
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
- create_database unless @database_created
64
+ unless self.class.database_created
65
+ self.class.create_database('/' << document_location[:database])
66
+ end
59
67
  if @id.present?
60
- response = put(document_uri[:uri], self)
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('/' << document_uri[:database], self)
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
- def get uri = document_uri[:uri]
70
- JSON.parse(request(Net::HTTP::Get.new(uri)).body)
71
- end
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
- def request(req)
94
- Net::HTTP.start(document_uri[:host], document_uri[:port]) { |http| http.request(req) }
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
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
- Bundler.require(:default, :test)
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 "create a document" do
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.document_uri "/foo"
27
- assert_equal "foo", @doc.document_uri[:database]
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.document_uri[:database]
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.3
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-09-29 00:00:00.000000000Z
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: &20647580 !ruby/object:Gem::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: *20647580
24
+ version_requirements: *11099760
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: shoulda
27
- requirement: &20647100 !ruby/object:Gem::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: *20647100
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: &20646620 !ruby/object:Gem::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: *20646620
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.6
92
+ rubygems_version: 1.8.10
78
93
  signing_key:
79
94
  specification_version: 3
80
95
  summary: A Hash with CouchDB persistence