dm-riak-adapter 0.0.2 → 0.0.3
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/README.md +4 -4
- data/lib/dm-riak-adapter/adapter.rb +71 -0
- data/lib/dm-riak-adapter/key.rb +8 -0
- data/lib/dm-riak-adapter.rb +4 -65
- data/spec/dm-riak-adapter_spec.rb +268 -3
- metadata +5 -3
data/README.md
CHANGED
@@ -14,19 +14,19 @@ Install the **dm-riak-adapter** gem:
|
|
14
14
|
|
15
15
|
## Usage
|
16
16
|
|
17
|
-
Require **dm-core** and **dm-riak-adapter**. Tell DataMapper to use the Riak adapter and set a namespace for your app. This namespace will prefix each bucket like
|
17
|
+
Require **dm-core** and **dm-riak-adapter**. Tell DataMapper to use the Riak adapter and set a namespace for your app. This namespace will prefix each bucket like `myapp:projects` `myapp:tasks`. You can also skip setting a namespace and the buckets wont have any prefix.
|
18
18
|
|
19
19
|
require 'dm-core'
|
20
20
|
require 'dm-riak-adapter'
|
21
21
|
|
22
22
|
DataMapper.setup :default, :adapter => 'riak', :namespace => 'myapp'
|
23
23
|
|
24
|
-
Continue Defining your models and properties as you normally would.
|
24
|
+
Continue Defining your models and properties as you normally would. Set the serial number as type **Key** to use Riak's server-assigned UUIDs.
|
25
25
|
|
26
26
|
class Project
|
27
27
|
include DataMapper::Resource
|
28
28
|
|
29
|
-
property :id,
|
29
|
+
property :id, Key
|
30
30
|
property :name, String
|
31
31
|
|
32
32
|
has n, :tasks
|
@@ -35,7 +35,7 @@ Continue Defining your models and properties as you normally would.
|
|
35
35
|
class Task
|
36
36
|
include DataMapper::Resource
|
37
37
|
|
38
|
-
property :id,
|
38
|
+
property :id, Key
|
39
39
|
property :summary, String
|
40
40
|
|
41
41
|
belongs_to :project
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module DataMapper::Adapters
|
2
|
+
class RiakAdapter < AbstractAdapter
|
3
|
+
def initialize(name, options)
|
4
|
+
super
|
5
|
+
@riak = Riak::Client.new(:prefix => options[:prefix] || 'riak')
|
6
|
+
@namespace = options[:namespace] ? options[:namespace] + ':' : ''
|
7
|
+
end
|
8
|
+
|
9
|
+
def create(resources)
|
10
|
+
create_objects(resources)
|
11
|
+
end
|
12
|
+
|
13
|
+
def read(query)
|
14
|
+
query.filter_records(objects_for(query.model)).each do |object|
|
15
|
+
query.fields.each do |property|
|
16
|
+
object[property.name.to_s] = property.typecast(object[property.name.to_s])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def update(attributes, collection)
|
22
|
+
attributes = attributes_as_fields(attributes)
|
23
|
+
|
24
|
+
objects_for(collection.query.model).each {|r| r.update(attributes)}
|
25
|
+
update_objects(collection)
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete(collection)
|
29
|
+
delete_objects(collection)
|
30
|
+
end
|
31
|
+
|
32
|
+
def flush(model)
|
33
|
+
bucket(model).keys.each {|key| bucket(model)[key].delete}
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def bucket(model)
|
39
|
+
@riak.bucket(@namespace + model.storage_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def objects_for(model)
|
43
|
+
bucket(model).keys.map {|key| bucket(model)[key].data}
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_objects(resources)
|
47
|
+
resources.each do |resource|
|
48
|
+
object = bucket(resource.model).new.store
|
49
|
+
initialize_serial(resource, object.key)
|
50
|
+
object.data = resource.attributes(:field)
|
51
|
+
object.store
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_objects(resources)
|
56
|
+
resources.each do |resource|
|
57
|
+
object = bucket(resource.model)[resource.key[0]]
|
58
|
+
object.data = resource.attributes(:field)
|
59
|
+
object.store
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete_objects(resources)
|
64
|
+
resources.each do |resource|
|
65
|
+
bucket(resource.model)[resource.key[0]].delete
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
const_added(:RiakAdapter)
|
71
|
+
end
|
data/lib/dm-riak-adapter.rb
CHANGED
@@ -1,67 +1,6 @@
|
|
1
|
+
$: << File.dirname(__FILE__)
|
2
|
+
|
1
3
|
require 'riak'
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
def initialize(name, options)
|
6
|
-
super
|
7
|
-
@riak = Riak::Client.new(:prefix => options[:prefix] || 'riak')
|
8
|
-
@namespace = options[:namespace] ? options[:namespace] + ':' : ''
|
9
|
-
end
|
10
|
-
|
11
|
-
def create(resources)
|
12
|
-
objects = objects_for(resources.first.model)
|
13
|
-
|
14
|
-
resources.each {|r| initialize_serial(r, objects.size.succ)}
|
15
|
-
create_objects(resources)
|
16
|
-
end
|
17
|
-
|
18
|
-
def read(query)
|
19
|
-
query.filter_records(objects_for(query.model).dup)
|
20
|
-
end
|
21
|
-
|
22
|
-
def update(attributes, collection)
|
23
|
-
attributes = attributes_as_fields(attributes)
|
24
|
-
|
25
|
-
objects_for(collection.query.model).each {|r| r.update(attributes)}
|
26
|
-
update_objects(collection)
|
27
|
-
end
|
28
|
-
|
29
|
-
def delete(collection)
|
30
|
-
delete_objects(collection)
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def bucket(model)
|
36
|
-
@riak.bucket(@namespace + model.storage_name)
|
37
|
-
end
|
38
|
-
|
39
|
-
def objects_for(model)
|
40
|
-
bucket(model).keys.map {|key| bucket(model)[key].data}
|
41
|
-
end
|
42
|
-
|
43
|
-
def create_objects(resources)
|
44
|
-
resources.each do |resource|
|
45
|
-
object = bucket(resource.model).new("#{resource.id}")
|
46
|
-
object.data = resource.attributes(:field)
|
47
|
-
object.store
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def update_objects(resources)
|
52
|
-
resources.each do |resource|
|
53
|
-
object = bucket(resource.model)["#{resource.id}"]
|
54
|
-
object.data = resource.attributes(:field)
|
55
|
-
object.store
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def delete_objects(resources)
|
60
|
-
resources.each do |resource|
|
61
|
-
bucket(resource.model)["#{resource.id}"].delete
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
const_added(:RiakAdapter)
|
67
|
-
end
|
5
|
+
require 'dm-riak-adapter/adapter'
|
6
|
+
require 'dm-riak-adapter/key'
|
@@ -1,16 +1,281 @@
|
|
1
1
|
$: << File.dirname(__FILE__)
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
|
-
require 'dm-core/spec/adapter_shared_spec'
|
5
4
|
|
6
5
|
describe DataMapper::Adapters::RiakAdapter do
|
7
6
|
before :all do
|
8
7
|
@adapter = DataMapper.setup(:default, :adapter => 'riak', :namespace => 'test')
|
8
|
+
|
9
|
+
class ::Heffalump
|
10
|
+
include DataMapper::Resource
|
11
|
+
|
12
|
+
property :id, Key
|
13
|
+
property :color, String
|
14
|
+
property :num_spots, Integer
|
15
|
+
property :striped, Boolean
|
16
|
+
end
|
9
17
|
end
|
10
18
|
|
11
19
|
after :all do
|
12
|
-
Heffalump
|
20
|
+
@adapter.flush Heffalump
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#create' do
|
24
|
+
it 'should not raise any errors' do
|
25
|
+
lambda {
|
26
|
+
Heffalump.create(:color => 'peach')
|
27
|
+
}.should_not raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should set the identity field for the resource' do
|
31
|
+
heffalump = Heffalump.new(:color => 'peach')
|
32
|
+
heffalump.id.should be_nil
|
33
|
+
heffalump.save
|
34
|
+
heffalump.id.should_not be_nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#read' do
|
39
|
+
before :all do
|
40
|
+
@heffalump = Heffalump.create(:color => 'brownish hue')
|
41
|
+
#just going to borrow this, so I can check the return values
|
42
|
+
@query = Heffalump.all.query
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should not raise any errors' do
|
46
|
+
lambda {
|
47
|
+
Heffalump.all()
|
48
|
+
}.should_not raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should return stuff' do
|
52
|
+
Heffalump.all.should be_include(@heffalump)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#update' do
|
57
|
+
before do
|
58
|
+
@heffalump = Heffalump.create(:color => 'indigo')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should not raise any errors' do
|
62
|
+
lambda {
|
63
|
+
@heffalump.color = 'violet'
|
64
|
+
@heffalump.save
|
65
|
+
}.should_not raise_error
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should not alter the identity field' do
|
69
|
+
id = @heffalump.id
|
70
|
+
@heffalump.color = 'violet'
|
71
|
+
@heffalump.save
|
72
|
+
@heffalump.id.should == id
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should update altered fields' do
|
76
|
+
@heffalump.color = 'violet'
|
77
|
+
@heffalump.save
|
78
|
+
Heffalump.get(*@heffalump.key).color.should == 'violet'
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should not alter other fields' do
|
82
|
+
color = @heffalump.color
|
83
|
+
@heffalump.num_spots = 3
|
84
|
+
@heffalump.save
|
85
|
+
Heffalump.get(*@heffalump.key).color.should == color
|
86
|
+
end
|
13
87
|
end
|
14
88
|
|
15
|
-
|
89
|
+
describe '#delete' do
|
90
|
+
before do
|
91
|
+
@heffalump = Heffalump.create(:color => 'forest green')
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should not raise any errors' do
|
95
|
+
lambda {
|
96
|
+
@heffalump.destroy
|
97
|
+
}.should_not raise_error
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should delete the requested resource' do
|
101
|
+
id = @heffalump.id
|
102
|
+
@heffalump.destroy
|
103
|
+
Heffalump.get(id).should be_nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe 'query matching' do
|
108
|
+
before :all do
|
109
|
+
@red = Heffalump.create(:color => 'red')
|
110
|
+
@two = Heffalump.create(:num_spots => 2)
|
111
|
+
@five = Heffalump.create(:num_spots => 5)
|
112
|
+
end
|
113
|
+
|
114
|
+
describe 'conditions' do
|
115
|
+
describe 'eql' do
|
116
|
+
it 'should be able to search for objects included in an inclusive range of values' do
|
117
|
+
Heffalump.all(:num_spots => 1..5).should be_include(@five)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should be able to search for objects included in an exclusive range of values' do
|
121
|
+
Heffalump.all(:num_spots => 1...6).should be_include(@five)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should not be able to search for values not included in an inclusive range of values' do
|
125
|
+
Heffalump.all(:num_spots => 1..4).should_not be_include(@five)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should not be able to search for values not included in an exclusive range of values' do
|
129
|
+
Heffalump.all(:num_spots => 1...5).should_not be_include(@five)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe 'not' do
|
134
|
+
it 'should be able to search for objects with not equal value' do
|
135
|
+
Heffalump.all(:color.not => 'red').should_not be_include(@red)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should include objects that are not like the value' do
|
139
|
+
Heffalump.all(:color.not => 'black').should be_include(@red)
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should be able to search for objects with not nil value' do
|
143
|
+
Heffalump.all(:color.not => nil).should be_include(@red)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should not include objects with a nil value' do
|
147
|
+
Heffalump.all(:color.not => nil).should_not be_include(@two)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should be able to search for object with a nil value using required properties' do
|
151
|
+
Heffalump.all(:id.not => nil).should == [ @red, @two, @five ]
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should be able to search for objects not in an empty list (match all)' do
|
155
|
+
Heffalump.all(:color.not => []).should == [ @red, @two, @five ]
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'should be able to search for objects in an empty list and another OR condition (match none on the empty list)' do
|
159
|
+
Heffalump.all(:conditions => DataMapper::Query::Conditions::Operation.new(
|
160
|
+
:or,
|
161
|
+
DataMapper::Query::Conditions::Comparison.new(:in, Heffalump.properties[:color], []),
|
162
|
+
DataMapper::Query::Conditions::Comparison.new(:in, Heffalump.properties[:num_spots], [5]))).should == [ @five ]
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should be able to search for objects not included in an array of values' do
|
166
|
+
Heffalump.all(:num_spots.not => [ 1, 3, 5, 7 ]).should be_include(@two)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should be able to search for objects not included in an array of values' do
|
170
|
+
Heffalump.all(:num_spots.not => [ 1, 3, 5, 7 ]).should_not be_include(@five)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should be able to search for objects not included in an inclusive range of values' do
|
174
|
+
Heffalump.all(:num_spots.not => 1..4).should be_include(@five)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should be able to search for objects not included in an exclusive range of values' do
|
178
|
+
Heffalump.all(:num_spots.not => 1...5).should be_include(@five)
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should not be able to search for values not included in an inclusive range of values' do
|
182
|
+
Heffalump.all(:num_spots.not => 1..5).should_not be_include(@five)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should not be able to search for values not included in an exclusive range of values' do
|
186
|
+
Heffalump.all(:num_spots.not => 1...6).should_not be_include(@five)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe 'like' do
|
191
|
+
it 'should be able to search for objects that match value' do
|
192
|
+
Heffalump.all(:color.like => '%ed').should be_include(@red)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should not search for objects that do not match the value' do
|
196
|
+
Heffalump.all(:color.like => '%blak%').should_not be_include(@red)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe 'regexp' do
|
201
|
+
before do
|
202
|
+
if (defined?(DataMapper::Adapters::Sqlite3Adapter) && @adapter.kind_of?(DataMapper::Adapters::Sqlite3Adapter) ||
|
203
|
+
defined?(DataMapper::Adapters::SqlserverAdapter) && @adapter.kind_of?(DataMapper::Adapters::SqlserverAdapter))
|
204
|
+
pending 'delegate regexp matches to same system that the InMemory and YAML adapters use'
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'should be able to search for objects that match value' do
|
209
|
+
Heffalump.all(:color => /ed/).should be_include(@red)
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should not be able to search for objects that do not match the value' do
|
213
|
+
Heffalump.all(:color => /blak/).should_not be_include(@red)
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should be able to do a negated search for objects that match value' do
|
217
|
+
Heffalump.all(:color.not => /blak/).should be_include(@red)
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'should not be able to do a negated search for objects that do not match value' do
|
221
|
+
Heffalump.all(:color.not => /ed/).should_not be_include(@red)
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
describe 'gt' do
|
227
|
+
it 'should be able to search for objects with value greater than' do
|
228
|
+
Heffalump.all(:num_spots.gt => 1).should be_include(@two)
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'should not find objects with a value less than' do
|
232
|
+
Heffalump.all(:num_spots.gt => 3).should_not be_include(@two)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe 'gte' do
|
237
|
+
it 'should be able to search for objects with value greater than' do
|
238
|
+
Heffalump.all(:num_spots.gte => 1).should be_include(@two)
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'should be able to search for objects with values equal to' do
|
242
|
+
Heffalump.all(:num_spots.gte => 2).should be_include(@two)
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'should not find objects with a value less than' do
|
246
|
+
Heffalump.all(:num_spots.gte => 3).should_not be_include(@two)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
describe 'lt' do
|
251
|
+
it 'should be able to search for objects with value less than' do
|
252
|
+
Heffalump.all(:num_spots.lt => 3).should be_include(@two)
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'should not find objects with a value less than' do
|
256
|
+
Heffalump.all(:num_spots.gt => 2).should_not be_include(@two)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe 'lte' do
|
261
|
+
it 'should be able to search for objects with value less than' do
|
262
|
+
Heffalump.all(:num_spots.lte => 3).should be_include(@two)
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'should be able to search for objects with values equal to' do
|
266
|
+
Heffalump.all(:num_spots.lte => 2).should be_include(@two)
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'should not find objects with a value less than' do
|
270
|
+
Heffalump.all(:num_spots.lte => 1).should_not be_include(@two)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe 'limits' do
|
276
|
+
it 'should be able to limit the objects' do
|
277
|
+
Heffalump.all(:limit => 2).length.should == 2
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
16
281
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 3
|
9
|
+
version: 0.0.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Mike Richards
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-29 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -54,6 +54,8 @@ extra_rdoc_files: []
|
|
54
54
|
files:
|
55
55
|
- README.md
|
56
56
|
- lib/dm-riak-adapter.rb
|
57
|
+
- lib/dm-riak-adapter/adapter.rb
|
58
|
+
- lib/dm-riak-adapter/key.rb
|
57
59
|
- spec/dm-riak-adapter_spec.rb
|
58
60
|
- spec/spec_helper.rb
|
59
61
|
has_rdoc: true
|