couchpillow 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +96 -26
- data/couchpillow.gemspec +4 -0
- data/lib/couchpillow/document.rb +127 -40
- data/lib/couchpillow/version.rb +1 -1
- data/lib/couchpillow.rb +3 -0
- data/test/test_document.rb +98 -5
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ccd762815a2494ec8a42b99e4d8feebf29d77fac
|
4
|
+
data.tar.gz: 9b0f6be497aa1a4cc2f0647ff0179953938a4be9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8771a637242a813b851b683c96fd12b8064c923ec0aafa86a491e40bf3e4d383760e4f428e756ad7518840a2990f07f5b3ff55dc4b605d7475c3a1aa3ac2e9a8
|
7
|
+
data.tar.gz: b4dd50c6540f695ba3f04ecf73299ce0f517563ea9843b237dd4132c49ee8944c60c81ee305afac6d3a9c2351a65b4c40ebbabaf56b3e7179281902625c59996
|
data/README.markdown
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
# CouchPillow
|
2
2
|
|
3
|
-
Light and comfortable Document integrity tool for Couchbase Server.
|
4
|
-
|
5
3
|
CouchPillow is a document integrity tool for Couchbase Documents to make sure
|
6
4
|
that all current and existing documents can work nicely with the current code.
|
7
5
|
|
8
6
|
CouchPillow separates itself from the database drivers, making it light and
|
9
7
|
independent from the implementation. Although it is initially designed to work
|
10
|
-
with Couchbase Server,
|
11
|
-
|
8
|
+
with Couchbase Server, it can be easily extended to other NoSQL databases, by
|
9
|
+
creating a driver that `respond_to?` the `set`, `delete`, `replace`, and `get`
|
10
|
+
methods.
|
12
11
|
|
13
12
|
|
14
13
|
## Features
|
@@ -29,7 +28,7 @@ long as they `respond_to?` the `set`, `delete`, `replace`, and `get` methods.
|
|
29
28
|
|
30
29
|
class MyDocument < CouchPillow::Document
|
31
30
|
type :my_document
|
32
|
-
attribute
|
31
|
+
attribute :stuff
|
33
32
|
end
|
34
33
|
|
35
34
|
CouchPillow.db = Couchbase.connect( bucket: 'default', host: 'localhost' )
|
@@ -39,9 +38,9 @@ long as they `respond_to?` the `set`, `delete`, `replace`, and `get` methods.
|
|
39
38
|
# {
|
40
39
|
# '_id': 'my_document::fb579b265cc005c47ff420a5c2a15d2b',
|
41
40
|
# '_type': 'my_document',
|
42
|
-
# 'stuff': 'hello',
|
43
41
|
# '_created_at': '2014-07-04 00:00:00 UTC'
|
44
42
|
# '_updated_at': '2014-07-04 00:00:00 UTC'
|
43
|
+
# 'stuff': 'hello',
|
45
44
|
# }
|
46
45
|
|
47
46
|
|
@@ -50,11 +49,11 @@ Retrieving Documents:
|
|
50
49
|
doc = MyDocument.get('my_document::fb579b265cc005c47ff420a5c2a15d2b')
|
51
50
|
doc.stuff # 'hello'
|
52
51
|
|
53
|
-
Specifying custom id
|
52
|
+
Specifying custom id:
|
54
53
|
|
55
54
|
class User < CouchPillow::Document
|
56
55
|
type :user
|
57
|
-
attribute
|
56
|
+
attribute :email
|
58
57
|
end
|
59
58
|
|
60
59
|
CouchPillow.db = Couchbase.connect( bucket: 'default', host: 'localhost' )
|
@@ -65,9 +64,9 @@ Specifying custom id if the auto-generated id is too confusing:
|
|
65
64
|
# {
|
66
65
|
# '_id': '123',
|
67
66
|
# '_type': 'user',
|
67
|
+
# '_created_at': '2014-07-04 00:00:00 UTC'
|
68
|
+
# '_updated_at': '2014-07-04 00:00:00 UTC'
|
68
69
|
# 'email': 'john@email.com',
|
69
|
-
# 'created_at': '2014-07-04 00:00:00 UTC'
|
70
|
-
# 'updated_at': '2014-07-04 00:00:00 UTC'
|
71
70
|
# }
|
72
71
|
|
73
72
|
### Attributes
|
@@ -75,12 +74,15 @@ Specifying custom id if the auto-generated id is too confusing:
|
|
75
74
|
Using Attribute Directives:
|
76
75
|
|
77
76
|
class User < CouchPillow::Document
|
78
|
-
type
|
79
|
-
attribute(:email)
|
80
|
-
.required
|
77
|
+
type :user
|
81
78
|
|
82
|
-
attribute
|
83
|
-
|
79
|
+
attribute :email do
|
80
|
+
required
|
81
|
+
end
|
82
|
+
|
83
|
+
attribute :first_name do
|
84
|
+
type String
|
85
|
+
end
|
84
86
|
end
|
85
87
|
|
86
88
|
CouchPillow.db = Couchbase.connect( bucket: 'default', host: 'localhost' )
|
@@ -102,19 +104,87 @@ List of Attribute Directives:
|
|
102
104
|
|
103
105
|
* `auto_convert`
|
104
106
|
|
105
|
-
|
106
|
-
|
107
|
+
Enables auto-conversion to the specified type. This gets ignored if `type`
|
108
|
+
directive is not specified.
|
107
109
|
|
108
110
|
* `default(&block)`
|
109
111
|
|
110
|
-
|
111
|
-
|
112
|
+
Runs the block to set the default value for this attribute, if it's missing
|
113
|
+
or nil. This is triggered on document creation and save.
|
112
114
|
|
113
115
|
* `content(&block)`
|
114
116
|
|
115
|
-
|
116
|
-
|
117
|
-
|
117
|
+
Custom validation method to check the value of the attribute. This is useful
|
118
|
+
in cases where you only want certain values to be stored (e.g a number
|
119
|
+
between 1-10 only)
|
120
|
+
|
121
|
+
|
122
|
+
### TTL Support
|
123
|
+
|
124
|
+
TTL is supported by passing options when saving the document. Using the above
|
125
|
+
example:
|
126
|
+
|
127
|
+
doc = User.new( { :email => 'john@email.com' } )
|
128
|
+
doc.save! ttl: 3600
|
129
|
+
|
130
|
+
|
131
|
+
### Multiple DB Connections Support
|
132
|
+
|
133
|
+
If you have a model that's accessing a different Couchbase bucket, or a
|
134
|
+
different Couchbase DB cluster entirely, you can specify the connections
|
135
|
+
via the `db` directive. Example:
|
136
|
+
|
137
|
+
CouchPillow.db = Couchbase.connect( bucket: 'default', host: 'localhost' )
|
138
|
+
memcached = Couchbase.connect( bucket: 'mymemcache_bucket', host: '128.128.128.128' )
|
139
|
+
|
140
|
+
class User < CouchPillow::Document
|
141
|
+
type :user
|
142
|
+
|
143
|
+
attribute :first_name do
|
144
|
+
type String
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class Token < CouchPillow::Document
|
149
|
+
type :token
|
150
|
+
|
151
|
+
db memcached
|
152
|
+
|
153
|
+
attribute :token do
|
154
|
+
type String
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
doc = User.new( { :first_name => 'John' } )
|
159
|
+
doc.save! # This gets saved to the localhost/bucket
|
160
|
+
|
161
|
+
token = Token.new( token: SecureRandom.uuid )
|
162
|
+
doc.save! # This gets saved to the 128.128.128.128/mymemcache_bucket
|
163
|
+
|
164
|
+
|
165
|
+
You can also specify multiple `db` directives. The first time the `db`
|
166
|
+
directive is called, it sets that connection as the primary connection, as the
|
167
|
+
above example shows. Any subsequent calls will insert that DB connection as
|
168
|
+
secondary connections, which will only be trigger on write (`save!`, `update!`,
|
169
|
+
and `delete!`).
|
170
|
+
|
171
|
+
|
172
|
+
class Token < CouchPillow::Document
|
173
|
+
type :token
|
174
|
+
|
175
|
+
db primary_connection
|
176
|
+
db migration
|
177
|
+
db backup
|
178
|
+
|
179
|
+
attribute :token do
|
180
|
+
type String
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
This can be useful as part of a migration process where you want to save
|
186
|
+
incoming data to another cluster while keeping the old one active.
|
187
|
+
|
118
188
|
|
119
189
|
|
120
190
|
### Migration
|
@@ -124,7 +194,7 @@ after a migration.
|
|
124
194
|
|
125
195
|
class User < CouchPillow::Document
|
126
196
|
rename :username, :nickname
|
127
|
-
attribute
|
197
|
+
attribute :nickname
|
128
198
|
end
|
129
199
|
u = User.new( { :username => 'jdoe' } )
|
130
200
|
u.nickname # 'jdoe'
|
@@ -138,11 +208,11 @@ as it reads them.
|
|
138
208
|
|
139
209
|
## Design Docs and Views
|
140
210
|
|
141
|
-
|
211
|
+
Design Docs and Views are outside the scope of CouchPillow.
|
142
212
|
However, given a design doc named `my_design_doc` and a View named `by_email`,
|
143
213
|
that returns documents as values, you can easily use it like this:
|
144
214
|
|
145
215
|
CouchPillow.db.design_docs['my_design_doc'].
|
146
|
-
by_email(:
|
147
|
-
new
|
216
|
+
by_email(:key => 'john@email.com').map do |v|
|
217
|
+
User.new(v.doc, v.id)
|
148
218
|
end
|
data/couchpillow.gemspec
CHANGED
@@ -14,6 +14,10 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
15
15
|
s.require_paths = ["lib"]
|
16
16
|
|
17
|
+
s.required_ruby_version = '~> 2.0'
|
18
|
+
|
19
|
+
s.add_runtime_dependency 'celluloid', '~> 0.16'
|
20
|
+
|
17
21
|
s.add_development_dependency 'minitest', '~> 5.3'
|
18
22
|
s.add_development_dependency 'mocha', '~> 1.1'
|
19
23
|
s.add_development_dependency 'rake', '~> 10.3'
|
data/lib/couchpillow/document.rb
CHANGED
@@ -8,21 +8,25 @@ module CouchPillow
|
|
8
8
|
|
9
9
|
RESERVED_KEYS = %i[_id _type _created_at _updated_at]
|
10
10
|
|
11
|
-
DEFAULT_TYPE = "
|
11
|
+
DEFAULT_TYPE = "couchpillow".freeze
|
12
12
|
|
13
13
|
|
14
|
-
attribute
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
attribute :_created_at do
|
15
|
+
required
|
16
|
+
type Time
|
17
|
+
auto_convert
|
18
|
+
default { Time.now.utc }
|
19
|
+
end
|
18
20
|
|
19
|
-
attribute
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
attribute :_updated_at do
|
22
|
+
required
|
23
|
+
type Time
|
24
|
+
auto_convert
|
25
|
+
default { Time.now.utc }
|
26
|
+
end
|
23
27
|
|
24
28
|
|
25
|
-
def initialize hash = {}, id = "#{self.class.
|
29
|
+
def initialize hash = {}, id = "#{self.class.doc_type}::#{SecureRandom.hex}"
|
26
30
|
@data = self.class.symbolize(hash)
|
27
31
|
|
28
32
|
@id = id
|
@@ -30,6 +34,8 @@ module CouchPillow
|
|
30
34
|
@data[:_created_at] ||= time
|
31
35
|
@data[:_updated_at] = time
|
32
36
|
|
37
|
+
@futures = []
|
38
|
+
|
33
39
|
rename!
|
34
40
|
whitelist!
|
35
41
|
assign_defaults!
|
@@ -47,13 +53,6 @@ module CouchPillow
|
|
47
53
|
end
|
48
54
|
|
49
55
|
|
50
|
-
# @private
|
51
|
-
#
|
52
|
-
def timestamp!
|
53
|
-
@data[:_updated_at] = Time.now.utc
|
54
|
-
end
|
55
|
-
|
56
|
-
|
57
56
|
# Save this document to the server
|
58
57
|
#
|
59
58
|
def save! opts = {}
|
@@ -62,16 +61,38 @@ module CouchPillow
|
|
62
61
|
timestamp!
|
63
62
|
validate!
|
64
63
|
to_save = @data.merge({
|
65
|
-
:_type => self.class.
|
64
|
+
:_type => self.class.doc_type
|
66
65
|
})
|
67
|
-
|
66
|
+
|
67
|
+
# write to all connections
|
68
|
+
result = self.class.default_db.set(@id, to_save, opts)
|
69
|
+
|
70
|
+
unless self.class.secondary_dbs.empty?
|
71
|
+
@futures << Celluloid::Future.new do
|
72
|
+
self.class.secondary_dbs.each do |db|
|
73
|
+
db.set(@id, to_save, opts)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
result
|
68
79
|
end
|
69
80
|
|
70
81
|
|
71
82
|
# Delete this document from the server.
|
72
83
|
#
|
73
84
|
def delete!
|
74
|
-
|
85
|
+
result = self.class.default_db.delete @id
|
86
|
+
|
87
|
+
unless self.class.secondary_dbs.empty?
|
88
|
+
@futures << Celluloid::Future.new do
|
89
|
+
self.class.secondary_dbs.each do |db|
|
90
|
+
db.delete @id
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
result
|
75
96
|
end
|
76
97
|
|
77
98
|
|
@@ -84,9 +105,20 @@ module CouchPillow
|
|
84
105
|
timestamp!
|
85
106
|
validate!
|
86
107
|
to_save = @data.merge({
|
87
|
-
:_type => self.class.
|
108
|
+
:_type => self.class.doc_type
|
88
109
|
})
|
89
|
-
|
110
|
+
|
111
|
+
result = self.class.default_db.replace @id, to_save
|
112
|
+
|
113
|
+
unless self.class.secondary_dbs.empty?
|
114
|
+
@futures << Celluloid::Future.new do
|
115
|
+
self.class.secondary_dbs.each do |db|
|
116
|
+
db.replace @id, to_save
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
result
|
90
122
|
end
|
91
123
|
|
92
124
|
|
@@ -100,21 +132,50 @@ module CouchPillow
|
|
100
132
|
end
|
101
133
|
rename!
|
102
134
|
whitelist!
|
135
|
+
auto_convert!
|
103
136
|
end
|
104
137
|
|
105
138
|
|
139
|
+
# Check if this Document has the key
|
140
|
+
#
|
106
141
|
def has? key
|
107
142
|
@data.has_key?(key)
|
108
143
|
end
|
109
144
|
|
110
145
|
|
146
|
+
# Convert this Document to a JSON string
|
147
|
+
#
|
111
148
|
def to_json *a
|
112
149
|
to_hash.to_json(*a)
|
113
150
|
end
|
114
151
|
|
115
152
|
|
153
|
+
# Convert this Document to a Hash
|
154
|
+
#
|
116
155
|
def to_hash
|
117
|
-
{ :_id => @id, :_type => self.class.
|
156
|
+
{ :_id => @id, :_type => self.class.doc_type }.merge!(@data)
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
# Helper to get the type of this Document.
|
161
|
+
# Can't really name this `type`. Need to avoid name conflict with Ruby's own `type` method.
|
162
|
+
#
|
163
|
+
def doc_type
|
164
|
+
self.class.doc_type
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
# Blocks until all pending tasks has completed.
|
169
|
+
# Returns the result of those tasks in an array.
|
170
|
+
#
|
171
|
+
def wait
|
172
|
+
result = []
|
173
|
+
until @futures.empty?
|
174
|
+
f = @futures.shift
|
175
|
+
result << f.value
|
176
|
+
end
|
177
|
+
|
178
|
+
result
|
118
179
|
end
|
119
180
|
|
120
181
|
|
@@ -138,7 +199,7 @@ module CouchPillow
|
|
138
199
|
end
|
139
200
|
|
140
201
|
|
141
|
-
# Assign default
|
202
|
+
# Assign default values.
|
142
203
|
#
|
143
204
|
def assign_defaults!
|
144
205
|
self.class.attributes.each do |k, attr|
|
@@ -157,13 +218,12 @@ module CouchPillow
|
|
157
218
|
|
158
219
|
|
159
220
|
# Go through each attribute, and validate the values.
|
160
|
-
# Validation also perform auto-conversion if auto-conversion is enabled
|
161
|
-
# for that attribute.
|
221
|
+
# Validation also perform auto-conversion if auto-conversion is enabled for that attribute.
|
162
222
|
#
|
163
223
|
def validate!
|
164
224
|
self.class.attributes.each do |k, attr|
|
165
225
|
if has?(k)
|
166
|
-
@data[k] = attr.validate(@data[k])
|
226
|
+
@data[k] = attr.validate(@data[k])
|
167
227
|
else
|
168
228
|
@data[k] = attr.trigger_default_directive if attr.has_default?
|
169
229
|
raise ValidationError, "Attribute '#{k}' is required" if attr.required? && !has?(k)
|
@@ -179,24 +239,14 @@ module CouchPillow
|
|
179
239
|
end
|
180
240
|
|
181
241
|
|
182
|
-
def _type
|
183
|
-
self.class._type
|
184
|
-
end
|
185
|
-
|
186
|
-
|
187
|
-
def _id
|
188
|
-
@id
|
189
|
-
end
|
190
|
-
|
191
|
-
|
192
242
|
# Get a Document given an id.
|
193
243
|
#
|
194
244
|
# @return nil if not found or Document is of a different type.
|
195
245
|
#
|
196
246
|
def self.get id
|
197
|
-
result =
|
247
|
+
result = default_db.get(id) and
|
198
248
|
type = result[:_type] || result["_type"] and
|
199
|
-
type ==
|
249
|
+
type == doc_type and
|
200
250
|
new(result, id) or
|
201
251
|
nil
|
202
252
|
end
|
@@ -220,10 +270,37 @@ module CouchPillow
|
|
220
270
|
end
|
221
271
|
|
222
272
|
|
273
|
+
# Set a DB connection. Overrides the default CouchPillow.db connection
|
274
|
+
# for the first time this method gets called. Subsequent calls will set
|
275
|
+
# secondary connections, which will only be used for write only.
|
276
|
+
#
|
277
|
+
# Example:
|
278
|
+
# db primary_db # use for both read and write
|
279
|
+
# db backup_db1 # write only
|
280
|
+
# db backup_db2 # write only
|
281
|
+
#
|
282
|
+
def self.db conn
|
283
|
+
# set the primary db connection
|
284
|
+
@primary_db ||= conn
|
285
|
+
|
286
|
+
# insert as backup db connections
|
287
|
+
if conn && @primary_db && conn != @primary_db
|
288
|
+
secondary_dbs << conn
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
|
223
293
|
private
|
224
294
|
|
225
295
|
|
226
|
-
|
296
|
+
# Timestamp this document
|
297
|
+
#
|
298
|
+
def timestamp!
|
299
|
+
@data[:_updated_at] = Time.now.utc
|
300
|
+
end
|
301
|
+
|
302
|
+
|
303
|
+
def self.doc_type
|
227
304
|
@type ||= DEFAULT_TYPE
|
228
305
|
end
|
229
306
|
|
@@ -233,6 +310,16 @@ module CouchPillow
|
|
233
310
|
end
|
234
311
|
|
235
312
|
|
313
|
+
def self.default_db
|
314
|
+
@default_db ||= (@primary_db || CouchPillow.db)
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
def self.secondary_dbs
|
319
|
+
@secondary_dbs ||= []
|
320
|
+
end
|
321
|
+
|
322
|
+
|
236
323
|
def self.symbolize hash
|
237
324
|
hash.inject({}) do |memo,(k,v)|
|
238
325
|
memo[k.to_sym] = v
|
data/lib/couchpillow/version.rb
CHANGED
data/lib/couchpillow.rb
CHANGED
data/test/test_document.rb
CHANGED
@@ -33,7 +33,7 @@ class TestDocument < Minitest::Test
|
|
33
33
|
|
34
34
|
def test_default_type
|
35
35
|
d = Document.new({}, "1")
|
36
|
-
assert_equal "
|
36
|
+
assert_equal "couchpillow", d.doc_type
|
37
37
|
end
|
38
38
|
|
39
39
|
|
@@ -41,7 +41,7 @@ class TestDocument < Minitest::Test
|
|
41
41
|
d = Class.new(Document) do
|
42
42
|
type 'test'
|
43
43
|
end.new
|
44
|
-
assert_equal "test", d.
|
44
|
+
assert_equal "test", d.doc_type
|
45
45
|
end
|
46
46
|
|
47
47
|
|
@@ -124,14 +124,14 @@ class TestDocument < Minitest::Test
|
|
124
124
|
def test_to_json
|
125
125
|
mock_time
|
126
126
|
d = Document.new({}, "1")
|
127
|
-
assert_equal "{\"_id\":\"1\",\"_type\":\"
|
127
|
+
assert_equal "{\"_id\":\"1\",\"_type\":\"couchpillow\",\"_created_at\":\"#{mock_time.to_s}\",\"_updated_at\":\"#{mock_time.to_s}\"}", d.to_json
|
128
128
|
end
|
129
129
|
|
130
130
|
|
131
131
|
def test_to_hash
|
132
132
|
mock_time
|
133
133
|
d = Document.new({}, "1")
|
134
|
-
assert_equal({ :_id => "1", :_created_at => mock_time, :_type => "
|
134
|
+
assert_equal({ :_id => "1", :_created_at => mock_time, :_type => "couchpillow", :_updated_at => mock_time }, d.to_hash)
|
135
135
|
end
|
136
136
|
|
137
137
|
|
@@ -201,7 +201,7 @@ class TestDocument < Minitest::Test
|
|
201
201
|
k = klass.new
|
202
202
|
k.foo = 100
|
203
203
|
k.save!
|
204
|
-
k_id = k.
|
204
|
+
k_id = k.id
|
205
205
|
|
206
206
|
d = klass.get(k_id)
|
207
207
|
assert_equal 100, d.foo
|
@@ -210,6 +210,7 @@ class TestDocument < Minitest::Test
|
|
210
210
|
|
211
211
|
def test_get_returns_nil
|
212
212
|
CouchPillow.db.expects(:get).with('123').returns(nil)
|
213
|
+
Document.expects(:default_db).returns(CouchPillow.db)
|
213
214
|
d = Document.get('123')
|
214
215
|
assert_equal nil, d
|
215
216
|
end
|
@@ -338,6 +339,25 @@ class TestDocument < Minitest::Test
|
|
338
339
|
end
|
339
340
|
|
340
341
|
|
342
|
+
def test_auto_convert_triggers_on_update
|
343
|
+
d = Class.new(Document) do
|
344
|
+
type 'test'
|
345
|
+
|
346
|
+
attribute :foo do
|
347
|
+
type(String)
|
348
|
+
auto_convert
|
349
|
+
end
|
350
|
+
|
351
|
+
attribute :not_auto do
|
352
|
+
type Integer
|
353
|
+
end
|
354
|
+
end.new( foo: 1, not_auto: "100" )
|
355
|
+
|
356
|
+
d.update( foo: 1776 )
|
357
|
+
assert_equal "1776", d.foo
|
358
|
+
end
|
359
|
+
|
360
|
+
|
341
361
|
def test_dsl_style
|
342
362
|
d = Class.new(Document) do
|
343
363
|
type 'test'
|
@@ -393,4 +413,77 @@ class TestDocument < Minitest::Test
|
|
393
413
|
d.save! ttl: 100
|
394
414
|
end
|
395
415
|
|
416
|
+
|
417
|
+
def test_custom_db_connection
|
418
|
+
conn1 = FakeCouchbaseServer.new
|
419
|
+
|
420
|
+
d = Class.new(Document) do
|
421
|
+
type 'test'
|
422
|
+
|
423
|
+
db conn1
|
424
|
+
|
425
|
+
attribute :foo do
|
426
|
+
type String
|
427
|
+
auto_convert
|
428
|
+
required
|
429
|
+
default { "tester" }
|
430
|
+
end
|
431
|
+
|
432
|
+
|
433
|
+
def initialize doc = {}
|
434
|
+
super(doc, "1")
|
435
|
+
end
|
436
|
+
|
437
|
+
end.new
|
438
|
+
d.foo = "hello"
|
439
|
+
d.save!
|
440
|
+
|
441
|
+
fromdefdb = CouchPillow.db.get("1")
|
442
|
+
assert_nil fromdefdb
|
443
|
+
|
444
|
+
fromprimdb = conn1.get("1")
|
445
|
+
assert_equal "hello", fromprimdb[:foo]
|
446
|
+
end
|
447
|
+
|
448
|
+
|
449
|
+
def test_multiple_db_connections
|
450
|
+
db1 = FakeCouchbaseServer.new
|
451
|
+
db2 = FakeCouchbaseServer.new
|
452
|
+
db3 = FakeCouchbaseServer.new
|
453
|
+
|
454
|
+
d = Class.new(Document) do
|
455
|
+
type 'test'
|
456
|
+
|
457
|
+
db db1
|
458
|
+
db db2
|
459
|
+
db db3
|
460
|
+
|
461
|
+
attribute :foo do
|
462
|
+
type String
|
463
|
+
auto_convert
|
464
|
+
required
|
465
|
+
default { "tester" }
|
466
|
+
end
|
467
|
+
|
468
|
+
|
469
|
+
def initialize doc = {}
|
470
|
+
super(doc, "1")
|
471
|
+
end
|
472
|
+
|
473
|
+
end.new
|
474
|
+
d.foo = "hello"
|
475
|
+
d.save!
|
476
|
+
|
477
|
+
res = d.wait
|
478
|
+
|
479
|
+
data = db1.get("1")
|
480
|
+
assert_equal "hello", data[:foo]
|
481
|
+
|
482
|
+
data = db2.get("1")
|
483
|
+
assert_equal "hello", data[:foo]
|
484
|
+
|
485
|
+
data = db3.get("1")
|
486
|
+
assert_equal "hello", data[:foo]
|
487
|
+
end
|
488
|
+
|
396
489
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couchpillow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Albert Tedja
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: celluloid
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.16'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.16'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: minitest
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -83,9 +97,9 @@ require_paths:
|
|
83
97
|
- lib
|
84
98
|
required_ruby_version: !ruby/object:Gem::Requirement
|
85
99
|
requirements:
|
86
|
-
- - "
|
100
|
+
- - "~>"
|
87
101
|
- !ruby/object:Gem::Version
|
88
|
-
version: '0'
|
102
|
+
version: '2.0'
|
89
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
104
|
requirements:
|
91
105
|
- - ">="
|