cooler 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cooler (0.0.2)
4
+ cooler (0.0.3)
5
5
  activesupport (>= 3.0.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -4,8 +4,73 @@
4
4
 
5
5
  _The Good-Hearted Leader_
6
6
 
7
- > Cooler Howard Smith has an outgoing and mellow personality and always keeps his
8
- > head up even in the most daring situations. He is smart, laid-back, friendly,
9
- > witty, and usually optimistic even when things get serious.
7
+ > Cooler Howard Smith has an outgoing and mellow personality and always keeps
8
+ > his head up even in the most daring situations. He is smart, laid-back,
9
+ > friendly, witty, and usually optimistic even when things get serious.
10
10
 
11
11
  A mini ORM, agnostic to key value store databases.
12
+
13
+ If you're in a hurry, and need to define some models that should be persisted,
14
+ in any Key-Value Store Database, this is the right gem.
15
+
16
+ ## Installation
17
+
18
+ Add `gem 'cooler'` to your Gemfile.
19
+
20
+ ## Define Adapter's set, get and delete
21
+
22
+ In an initializer, you'll need to specify how to set, get and delete a key.
23
+ Let's say that you use Redis, then you want to do something similar to:
24
+
25
+ ```ruby
26
+ redis = Redis.new
27
+
28
+ Cooler::Adapater.set = ->(key, value) { redis.set(key, value.to_json) }
29
+ Cooler::Adapater.get = ->(key) do
30
+ result = Bloodhound.redis.get(key) and JSON.parse(result)
31
+ end
32
+ Cooler::Adapater.delete = ->(key) { redis.del(key) }
33
+ ```
34
+
35
+ That's it.
36
+
37
+ ## Define your models
38
+
39
+ Defining a model is as easy as 1, 2, 3.
40
+
41
+ ```ruby
42
+ # A model should inherit from Struct, attributes defined there are PERSISTED
43
+ # in the database.
44
+ class User < Struct.new(:login, :age, :encrypted_password, :created_at)
45
+ # You must include Cooler::Model
46
+ include Cooler::Model
47
+
48
+ # Any attribute accessor, or instance variables, are NOT STORED in the
49
+ # database, however you can initialize an object with these attributes.
50
+ attr_accessor :password
51
+
52
+ # You can set defaults for any of the attributes.
53
+ default :age, 18
54
+ default :encrypted_password,
55
+ ->(user) { Digest::MD5.hexdigest(user.password) }
56
+ default :created_at, -> { Time.now.utc }
57
+
58
+ # To define the key for a Model, you need to pass a block, and return an
59
+ # String that will be the key to store the object.
60
+ key { |user| "user_#{user.login}" }
61
+ end
62
+
63
+ # You can create a new instance, passing its atributes:
64
+ user = User.new(login: 'cooler', age: 20, password: 'im_cooler')
65
+ user.save
66
+
67
+ # You can also get any stored object, passing a Hash as argument, or
68
+ # specifying the exact key.
69
+ user = User.get(login: 'cooler') # or User.get('user_cooler')
70
+ user.age = 10
71
+ user.save
72
+ ```
73
+
74
+ ## License
75
+
76
+ MIT
@@ -7,6 +7,9 @@ module Cooler
7
7
 
8
8
  # Gets the set block.
9
9
  attr_reader :set
10
+
11
+ # Gets the delete block.
12
+ attr_reader :delete
10
13
  end
11
14
 
12
15
  # Sets the block that handles getting a key.
@@ -48,5 +51,20 @@ module Cooler
48
51
  raise 'Argument must be a block' unless Proc === block
49
52
  @set = block
50
53
  end
54
+
55
+ # Sets the block that handles deleting a key.
56
+ #
57
+ # block - The block that receives as argument the String with the key to
58
+ # delete.
59
+ #
60
+ # Examples
61
+ #
62
+ # Cooler::Adapter.delete = ->(key) { redis.del(key) }
63
+ #
64
+ # Returns nothing.
65
+ def self.delete=(block)
66
+ raise 'Argument must be a block' unless Proc === block
67
+ @delete = block
68
+ end
51
69
  end
52
70
  end
data/lib/cooler/errors.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  module Cooler
2
- class NotFound < NameError
2
+ class KeyNotFound < NameError
3
3
  def http_status
4
4
  404
5
5
  end
6
6
  end
7
7
 
8
- class InvalidRecord < StandardError
8
+ class InvalidObject < StandardError
9
9
  def http_status
10
10
  406
11
11
  end
data/lib/cooler/model.rb CHANGED
@@ -106,11 +106,11 @@ module Cooler
106
106
  # key - The String that contains the key to query the object.
107
107
  #
108
108
  # Return a Model instance.
109
- # Raises Cooler::NotFound if not found. Compatible with
109
+ # Raises Cooler::KeyNotFound if not found. Compatible with
110
110
  # Sinatra::NotFound;
111
111
  # http://www.sinatrarb.com/intro.html#Not%20Found
112
112
  def get!(key)
113
- get(key) || raise(Cooler::NotFound)
113
+ get(key) || raise(Cooler::KeyNotFound)
114
114
  end
115
115
 
116
116
  # Initializes a new instance, and saves it at the same time.
@@ -162,7 +162,9 @@ module Cooler
162
162
  #
163
163
  # Returns the serialized Hash.
164
164
  def serializable_hash
165
- Hash[*each_pair.map { |k, v| [k, v] }.flatten]
165
+ hash = {}
166
+ each_pair { |key, value| hash[key] = value }
167
+ hash
166
168
  end
167
169
 
168
170
  # Saves persisted attributes to the database.
@@ -177,9 +179,9 @@ module Cooler
177
179
  # not able to save it.
178
180
  #
179
181
  # Returns nothing.
180
- # Raises Cooler::InvalidRecord if not able to save it.
182
+ # Raises Cooler::InvalidObject if not able to save it.
181
183
  def save!
182
- raise Cooler::InvalidRecord unless save
184
+ raise Cooler::InvalidObject unless save
183
185
  end
184
186
 
185
187
  private
@@ -1,3 +1,3 @@
1
1
  module Cooler
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -102,7 +102,8 @@ describe Cooler::Model do
102
102
 
103
103
  it 'should raise an exception if no results' do
104
104
  mock(Cooler::Adapter).get { ->(k) { nil } }
105
- expect { TestModel.get!('test_bacon') }.to raise_error(Cooler::NotFound)
105
+ expect { TestModel.get!('test_bacon') }.
106
+ to raise_error(Cooler::KeyNotFound)
106
107
  end
107
108
  end
108
109
 
@@ -140,6 +141,12 @@ describe Cooler::Model do
140
141
  instance.serializable_hash.keys.should include(:foo)
141
142
  instance.serializable_hash[:foo].should == 'bar'
142
143
  end
144
+
145
+ it 'should allow an Array as a value' do
146
+ instance = TestModelUsingAttrAccessors.new(foo: [1, 2, 3, 4])
147
+ expect { instance.serializable_hash }.to_not raise_error
148
+ instance.serializable_hash[:foo].should == [1, 2, 3, 4]
149
+ end
143
150
  end
144
151
 
145
152
  context 'using attribute accessors' do
@@ -193,7 +200,7 @@ describe Cooler::Model do
193
200
  describe '.save!' do
194
201
  it 'should raise an exception if not saved' do
195
202
  mock(instance = TestModelForSave.new).save { false }
196
- expect { instance.save! }.to raise_error(Cooler::InvalidRecord)
203
+ expect { instance.save! }.to raise_error(Cooler::InvalidObject)
197
204
  end
198
205
  end
199
206
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cooler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-10 00:00:00.000000000 Z
12
+ date: 2013-01-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -111,7 +111,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
111
  version: '0'
112
112
  segments:
113
113
  - 0
114
- hash: -3025709922472475179
114
+ hash: 3227870062238590793
115
115
  required_rubygems_version: !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
@@ -120,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
120
  version: '0'
121
121
  segments:
122
122
  - 0
123
- hash: -3025709922472475179
123
+ hash: 3227870062238590793
124
124
  requirements: []
125
125
  rubyforge_project:
126
126
  rubygems_version: 1.8.23