couchpillow 0.4.3 → 0.4.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.
- 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
|
- - ">="
|