mattetti-couchrest 0.2.1.0 → 0.13
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 +6 -31
- data/Rakefile +1 -1
- data/examples/model/example.rb +13 -19
- data/lib/couchrest/core/database.rb +4 -3
- data/lib/couchrest/core/model.rb +615 -0
- data/lib/couchrest/core/response.rb +4 -5
- data/lib/couchrest/core/server.rb +1 -1
- data/lib/couchrest/mixins/callbacks.rb +33 -74
- data/lib/couchrest/mixins/design_doc.rb +1 -2
- data/lib/couchrest/mixins/document_queries.rb +1 -1
- data/lib/couchrest/mixins/extended_document_mixins.rb +1 -2
- data/lib/couchrest/mixins/properties.rb +3 -8
- data/lib/couchrest/mixins/validation.rb +1 -2
- data/lib/couchrest/mixins/views.rb +5 -5
- data/lib/couchrest/monkeypatches.rb +48 -65
- data/lib/couchrest/more/extended_document.rb +8 -75
- data/lib/couchrest/more/property.rb +1 -12
- data/lib/couchrest/support/class.rb +132 -148
- data/lib/couchrest.rb +8 -33
- data/spec/couchrest/core/database_spec.rb +23 -28
- data/spec/couchrest/core/model_spec.rb +856 -0
- data/spec/couchrest/more/casted_model_spec.rb +0 -14
- data/spec/couchrest/more/extended_doc_spec.rb +4 -450
- data/spec/couchrest/more/property_spec.rb +5 -16
- data/spec/spec_helper.rb +0 -4
- metadata +3 -16
- data/lib/couchrest/mixins/extended_attachments.rb +0 -68
- data/lib/couchrest/validation/validators/confirmation_validator.rb +0 -99
- data/spec/couchrest/more/casted_extended_doc_spec.rb +0 -40
- data/spec/couchrest/more/extended_doc_attachment_spec.rb +0 -129
- data/spec/couchrest/more/extended_doc_view_spec.rb +0 -206
- data/spec/couchrest/support/class_spec.rb +0 -59
- data/spec/fixtures/more/article.rb +0 -34
- data/spec/fixtures/more/course.rb +0 -14
- data/spec/fixtures/more/event.rb +0 -6
- data/spec/fixtures/more/person.rb +0 -8
- data/spec/fixtures/more/question.rb +0 -6
@@ -1,7 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'support', 'class')
|
2
2
|
|
3
3
|
# Extracted from ActiveSupport::Callbacks written by Yehuda Katz
|
4
|
-
# http://github.com/wycats/rails/raw/abstract_controller/activesupport/lib/active_support/new_callbacks.rb
|
5
4
|
# http://github.com/wycats/rails/raw/18b405f154868204a8f332888871041a7bad95e1/activesupport/lib/active_support/callbacks.rb
|
6
5
|
|
7
6
|
module CouchRest
|
@@ -12,7 +11,7 @@ module CouchRest
|
|
12
11
|
#
|
13
12
|
# Example:
|
14
13
|
# class Storage
|
15
|
-
# include
|
14
|
+
# include CouchRest::Callbacks
|
16
15
|
#
|
17
16
|
# define_callbacks :save
|
18
17
|
# end
|
@@ -46,7 +45,7 @@ module CouchRest
|
|
46
45
|
#
|
47
46
|
# Example:
|
48
47
|
# class Storage
|
49
|
-
# include
|
48
|
+
# include CouchRest::Callbacks
|
50
49
|
#
|
51
50
|
# define_callbacks :save
|
52
51
|
#
|
@@ -86,8 +85,8 @@ module CouchRest
|
|
86
85
|
klass.extend ClassMethods
|
87
86
|
end
|
88
87
|
|
89
|
-
def run_callbacks(kind, options = {}
|
90
|
-
send("_run_#{kind}_callbacks"
|
88
|
+
def run_callbacks(kind, options = {})
|
89
|
+
send("_run_#{kind}_callbacks")
|
91
90
|
end
|
92
91
|
|
93
92
|
class Callback
|
@@ -167,13 +166,9 @@ module CouchRest
|
|
167
166
|
|
168
167
|
# This will supply contents for before and around filters, and no
|
169
168
|
# contents for after filters (for the forward pass).
|
170
|
-
def start(key = nil,
|
171
|
-
object, terminator = (options || {}).values_at(:object, :terminator)
|
172
|
-
|
169
|
+
def start(key = nil, object = nil)
|
173
170
|
return if key && !object.send("_one_time_conditions_valid_#{@callback_id}?")
|
174
171
|
|
175
|
-
terminator ||= false
|
176
|
-
|
177
172
|
# options[0] is the compiled form of supplied conditions
|
178
173
|
# options[1] is the "end" for the conditional
|
179
174
|
|
@@ -182,14 +177,8 @@ module CouchRest
|
|
182
177
|
# if condition # before_save :filter_name, :if => :condition
|
183
178
|
# filter_name
|
184
179
|
# end
|
185
|
-
filter
|
186
|
-
|
187
|
-
result = #{@filter}
|
188
|
-
halted ||= (#{terminator})
|
189
|
-
end
|
190
|
-
RUBY_EVAL
|
191
|
-
[@compiled_options[0], filter, @compiled_options[1]].compact.join("\n")
|
192
|
-
else
|
180
|
+
[@compiled_options[0], @filter, @compiled_options[1]].compact.join("\n")
|
181
|
+
elsif @compiled_options[0]
|
193
182
|
# Compile around filters with conditions into proxy methods
|
194
183
|
# that contain the conditions.
|
195
184
|
#
|
@@ -207,8 +196,8 @@ module CouchRest
|
|
207
196
|
|
208
197
|
name = "_conditional_callback_#{@kind}_#{next_id}"
|
209
198
|
txt = <<-RUBY_EVAL
|
210
|
-
def #{name}
|
211
|
-
#{@compiled_options[0]
|
199
|
+
def #{name}
|
200
|
+
#{@compiled_options[0]}
|
212
201
|
#{@filter} do
|
213
202
|
yield self
|
214
203
|
end
|
@@ -218,16 +207,16 @@ module CouchRest
|
|
218
207
|
end
|
219
208
|
RUBY_EVAL
|
220
209
|
@klass.class_eval(txt)
|
221
|
-
"#{name}
|
210
|
+
"#{name} do"
|
211
|
+
else
|
212
|
+
"#{@filter} do"
|
222
213
|
end
|
223
214
|
end
|
224
215
|
end
|
225
216
|
|
226
217
|
# This will supply contents for around and after filters, but not
|
227
218
|
# before filters (for the backward pass).
|
228
|
-
def end(key = nil,
|
229
|
-
object = (options || {})[:object]
|
230
|
-
|
219
|
+
def end(key = nil, object = nil)
|
231
220
|
return if key && !object.send("_one_time_conditions_valid_#{@callback_id}?")
|
232
221
|
|
233
222
|
if @kind == :around || @kind == :after
|
@@ -310,7 +299,7 @@ module CouchRest
|
|
310
299
|
# This method_missing is supplied to catch callbacks with keys and create
|
311
300
|
# the appropriate callback for future use.
|
312
301
|
def method_missing(meth, *args, &blk)
|
313
|
-
if meth.to_s =~ /
|
302
|
+
if meth.to_s =~ /_run_(\w+)_(\w+)_(\w+)_callbacks/
|
314
303
|
return self.class._create_and_run_keyed_callback($1, $2.to_sym, $3.to_sym, self, &blk)
|
315
304
|
end
|
316
305
|
super
|
@@ -318,31 +307,25 @@ module CouchRest
|
|
318
307
|
|
319
308
|
# An Array with a compile method
|
320
309
|
class CallbackChain < Array
|
321
|
-
def
|
322
|
-
@symbol = symbol
|
323
|
-
end
|
324
|
-
|
325
|
-
def compile(key = nil, options = {})
|
310
|
+
def compile(key = nil, object = nil)
|
326
311
|
method = []
|
327
|
-
method << "halted = false"
|
328
312
|
each do |callback|
|
329
|
-
method << callback.start(key,
|
313
|
+
method << callback.start(key, object)
|
330
314
|
end
|
331
|
-
method << "yield self
|
315
|
+
method << "yield self"
|
332
316
|
reverse_each do |callback|
|
333
|
-
method << callback.end(key,
|
317
|
+
method << callback.end(key, object)
|
334
318
|
end
|
335
319
|
method.compact.join("\n")
|
336
320
|
end
|
337
321
|
|
338
322
|
def clone(klass)
|
339
|
-
|
340
|
-
chain.push(*map {|c| c.clone(klass)})
|
323
|
+
CallbackChain.new(map {|c| c.clone(klass)})
|
341
324
|
end
|
342
325
|
end
|
343
326
|
|
344
327
|
module ClassMethods
|
345
|
-
CHAINS = {:before => :before, :around => :before, :after => :after}
|
328
|
+
CHAINS = {:before => :before, :around => :before, :after => :after}
|
346
329
|
|
347
330
|
# Make the _run_save_callbacks method. The generated method takes
|
348
331
|
# a block that it'll yield to. It'll call the before and around filters
|
@@ -355,18 +338,16 @@ module CouchRest
|
|
355
338
|
# The _run_save_callbacks method can optionally take a key, which
|
356
339
|
# will be used to compile an optimized callback method for each
|
357
340
|
# key. See #define_callbacks for more information.
|
358
|
-
def _define_runner(symbol, str, options)
|
359
|
-
|
341
|
+
def _define_runner(symbol, str, options)
|
342
|
+
self.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
360
343
|
def _run_#{symbol}_callbacks(key = nil)
|
361
344
|
if key
|
362
|
-
send("
|
345
|
+
send("_run_\#{self.class}_#{symbol}_\#{key}_callbacks") { yield }
|
363
346
|
else
|
364
347
|
#{str}
|
365
348
|
end
|
366
349
|
end
|
367
350
|
RUBY_EVAL
|
368
|
-
|
369
|
-
class_eval str, __FILE__, __LINE__ + 1
|
370
351
|
|
371
352
|
before_name, around_name, after_name =
|
372
353
|
options.values_at(:before, :after, :around)
|
@@ -378,18 +359,15 @@ module CouchRest
|
|
378
359
|
def _create_and_run_keyed_callback(klass, kind, key, obj, &blk)
|
379
360
|
@_keyed_callbacks ||= {}
|
380
361
|
@_keyed_callbacks[[kind, key]] ||= begin
|
381
|
-
str = self.send("_#{kind}_callbacks").compile(key,
|
382
|
-
|
362
|
+
str = self.send("_#{kind}_callbacks").compile(key, obj)
|
383
363
|
self.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
384
|
-
def
|
364
|
+
def _run_#{klass}_#{kind}_#{key}_callbacks
|
385
365
|
#{str}
|
386
366
|
end
|
387
367
|
RUBY_EVAL
|
388
|
-
|
389
368
|
true
|
390
369
|
end
|
391
|
-
|
392
|
-
obj.send("_run__#{klass.split("::").last}__#{kind}__#{key}__callbacks", &blk)
|
370
|
+
obj.send("_run_#{klass}_#{kind}_#{key}_callbacks", &blk)
|
393
371
|
end
|
394
372
|
|
395
373
|
# Define callbacks.
|
@@ -424,32 +402,20 @@ module CouchRest
|
|
424
402
|
# method that took into consideration the per_key conditions. This
|
425
403
|
# is a speed improvement for ActionPack.
|
426
404
|
def define_callbacks(*symbols)
|
427
|
-
terminator = symbols.pop if symbols.last.is_a?(String)
|
428
405
|
symbols.each do |symbol|
|
429
|
-
self.class_inheritable_accessor("_#{symbol}_terminator")
|
430
|
-
self.send("_#{symbol}_terminator=", terminator)
|
431
406
|
self.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
432
407
|
class_inheritable_accessor :_#{symbol}_callbacks
|
433
|
-
self._#{symbol}_callbacks = CallbackChain.new
|
408
|
+
self._#{symbol}_callbacks = CallbackChain.new
|
434
409
|
|
435
|
-
def self.#{symbol}_callback(*filters, &blk)
|
436
|
-
type = [:before, :after, :around].include?(filters.first) ? filters.shift : :before
|
410
|
+
def self.#{symbol}_callback(type, *filters, &blk)
|
437
411
|
options = filters.last.is_a?(Hash) ? filters.pop : {}
|
438
412
|
filters.unshift(blk) if block_given?
|
439
|
-
|
440
|
-
filters.map! do |filter|
|
441
|
-
# overrides parent class
|
442
|
-
self._#{symbol}_callbacks.delete_if {|c| c.matches?(type, :#{symbol}, filter)}
|
443
|
-
Callback.new(filter, type, options.dup, self, :#{symbol})
|
444
|
-
end
|
413
|
+
filters.map! {|f| Callback.new(f, type, options.dup, self, :#{symbol})}
|
445
414
|
self._#{symbol}_callbacks.push(*filters)
|
446
|
-
_define_runner(:#{symbol},
|
447
|
-
self._#{symbol}_callbacks.compile(nil, :terminator => _#{symbol}_terminator),
|
448
|
-
options)
|
415
|
+
_define_runner(:#{symbol}, self._#{symbol}_callbacks.compile, options)
|
449
416
|
end
|
450
417
|
|
451
|
-
def self.skip_#{symbol}_callback(*filters, &blk)
|
452
|
-
type = [:before, :after, :around].include?(filters.first) ? filters.shift : :before
|
418
|
+
def self.skip_#{symbol}_callback(type, *filters, &blk)
|
453
419
|
options = filters.last.is_a?(Hash) ? filters.pop : {}
|
454
420
|
filters.unshift(blk) if block_given?
|
455
421
|
filters.each do |filter|
|
@@ -462,22 +428,15 @@ module CouchRest
|
|
462
428
|
else
|
463
429
|
self._#{symbol}_callbacks.delete(filter)
|
464
430
|
end
|
465
|
-
_define_runner(:#{symbol},
|
466
|
-
self._#{symbol}_callbacks.compile(nil, :terminator => _#{symbol}_terminator),
|
467
|
-
options)
|
431
|
+
_define_runner(:#{symbol}, self._#{symbol}_callbacks.compile, options)
|
468
432
|
end
|
469
433
|
|
470
434
|
end
|
471
435
|
|
472
|
-
def self.reset_#{symbol}_callbacks
|
473
|
-
self._#{symbol}_callbacks = CallbackChain.new(:#{symbol})
|
474
|
-
_define_runner(:#{symbol}, self._#{symbol}_callbacks.compile, {})
|
475
|
-
end
|
476
|
-
|
477
436
|
self.#{symbol}_callback(:before)
|
478
437
|
RUBY_EVAL
|
479
438
|
end
|
480
439
|
end
|
481
440
|
end
|
482
441
|
end
|
483
|
-
end
|
442
|
+
end
|
@@ -14,9 +14,8 @@ module CouchRest
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def design_doc_slug
|
17
|
-
return design_doc_slug_cache if
|
17
|
+
return design_doc_slug_cache if design_doc_slug_cache && design_doc_fresh
|
18
18
|
funcs = []
|
19
|
-
design_doc ||= Design.new(default_design_doc)
|
20
19
|
design_doc['views'].each do |name, view|
|
21
20
|
funcs << "#{name}/#{view['map']}#{view['reduce']}"
|
22
21
|
end
|
@@ -2,5 +2,4 @@ require File.join(File.dirname(__FILE__), 'properties')
|
|
2
2
|
require File.join(File.dirname(__FILE__), 'document_queries')
|
3
3
|
require File.join(File.dirname(__FILE__), 'views')
|
4
4
|
require File.join(File.dirname(__FILE__), 'design_doc')
|
5
|
-
require File.join(File.dirname(__FILE__), 'validation')
|
6
|
-
require File.join(File.dirname(__FILE__), 'extended_attachments')
|
5
|
+
require File.join(File.dirname(__FILE__), 'validation')
|
@@ -40,8 +40,8 @@ module CouchRest
|
|
40
40
|
key = self.has_key?(property.name) ? property.name : property.name.to_sym
|
41
41
|
target = property.type
|
42
42
|
if target.is_a?(Array)
|
43
|
-
next unless self[key]
|
44
43
|
klass = ::CouchRest.constantize(target[0])
|
44
|
+
|
45
45
|
self[property.name] = self[key].collect do |value|
|
46
46
|
# Auto parse Time objects
|
47
47
|
obj = ( (property.init_method == 'new') && klass == Time) ? Time.parse(value) : klass.send(property.init_method, value)
|
@@ -55,14 +55,9 @@ module CouchRest
|
|
55
55
|
else
|
56
56
|
# Let people use :send as a Time parse arg
|
57
57
|
klass = ::CouchRest.constantize(target)
|
58
|
-
# I'm not convince we should or should not create a new instance if we are casting a doc/extended doc without default value and nothing was passed
|
59
|
-
# unless (property.casted &&
|
60
|
-
# (klass.superclass == CouchRest::ExtendedDocument || klass.superclass == CouchRest::Document) &&
|
61
|
-
# (self[key].nil? || property.default.nil?))
|
62
58
|
klass.send(property.init_method, self[key])
|
63
|
-
#end
|
64
59
|
end
|
65
|
-
self[
|
60
|
+
self[key].casted_by = self if self[key].respond_to?(:casted_by)
|
66
61
|
end
|
67
62
|
end
|
68
63
|
end
|
@@ -70,7 +65,7 @@ module CouchRest
|
|
70
65
|
module ClassMethods
|
71
66
|
|
72
67
|
def property(name, options={})
|
73
|
-
define_property(name, options) unless
|
68
|
+
define_property(name, options) unless properties.map{|p| p.name}.include?(name.to_s)
|
74
69
|
end
|
75
70
|
|
76
71
|
protected
|
@@ -43,7 +43,6 @@ require File.join(dir, 'validators', 'format_validator')
|
|
43
43
|
require File.join(dir, 'validators', 'length_validator')
|
44
44
|
require File.join(dir, 'validators', 'numeric_validator')
|
45
45
|
require File.join(dir, 'validators', 'method_validator')
|
46
|
-
require File.join(dir, 'validators', 'confirmation_validator')
|
47
46
|
|
48
47
|
module CouchRest
|
49
48
|
module Validation
|
@@ -148,7 +147,7 @@ module CouchRest
|
|
148
147
|
module ClassMethods
|
149
148
|
include CouchRest::Validation::ValidatesPresent
|
150
149
|
include CouchRest::Validation::ValidatesAbsent
|
151
|
-
include CouchRest::Validation::ValidatesIsConfirmed
|
150
|
+
# include CouchRest::Validation::ValidatesIsConfirmed
|
152
151
|
# include CouchRest::Validation::ValidatesIsPrimitive
|
153
152
|
# include CouchRest::Validation::ValidatesIsAccepted
|
154
153
|
include CouchRest::Validation::ValidatesFormat
|
@@ -95,7 +95,7 @@ module CouchRest
|
|
95
95
|
end
|
96
96
|
|
97
97
|
# Dispatches to any named view.
|
98
|
-
def view
|
98
|
+
def view name, query={}, &block
|
99
99
|
unless design_doc_fresh
|
100
100
|
refresh_design_doc
|
101
101
|
end
|
@@ -128,9 +128,9 @@ module CouchRest
|
|
128
128
|
|
129
129
|
private
|
130
130
|
|
131
|
-
def fetch_view_with_docs
|
132
|
-
if raw
|
133
|
-
fetch_view
|
131
|
+
def fetch_view_with_docs name, opts, raw=false, &block
|
132
|
+
if raw
|
133
|
+
fetch_view name, opts, &block
|
134
134
|
else
|
135
135
|
begin
|
136
136
|
view = fetch_view name, opts.merge({:include_docs => true}), &block
|
@@ -138,7 +138,7 @@ module CouchRest
|
|
138
138
|
rescue
|
139
139
|
# fallback for old versions of couchdb that don't
|
140
140
|
# have include_docs support
|
141
|
-
view = fetch_view
|
141
|
+
view = fetch_view name, opts, &block
|
142
142
|
view['rows'].collect{|r|new(database.get(r['id']))} if view['rows']
|
143
143
|
end
|
144
144
|
end
|
@@ -31,19 +31,13 @@ if RUBY_VERSION.to_f < 1.9
|
|
31
31
|
class Net::BufferedIO #:nodoc:
|
32
32
|
alias :old_rbuf_fill :rbuf_fill
|
33
33
|
def rbuf_fill
|
34
|
-
|
35
|
-
|
34
|
+
begin
|
35
|
+
@rbuf << @io.read_nonblock(65536)
|
36
|
+
rescue Errno::EWOULDBLOCK
|
37
|
+
if IO.select([@io], nil, nil, @read_timeout)
|
36
38
|
@rbuf << @io.read_nonblock(65536)
|
37
|
-
|
38
|
-
|
39
|
-
retry
|
40
|
-
else
|
41
|
-
raise Timeout::TimeoutError
|
42
|
-
end
|
43
|
-
end
|
44
|
-
else
|
45
|
-
timeout(@read_timeout) do
|
46
|
-
@rbuf << @io.sysread(65536)
|
39
|
+
else
|
40
|
+
raise Timeout::TimeoutError
|
47
41
|
end
|
48
42
|
end
|
49
43
|
end
|
@@ -62,58 +56,47 @@ module RestClient
|
|
62
56
|
:url => url,
|
63
57
|
:headers => headers)
|
64
58
|
end
|
65
|
-
|
66
|
-
# class Request
|
67
|
-
#
|
68
|
-
# def establish_connection(uri)
|
69
|
-
# Thread.current[:connection].finish if (Thread.current[:connection] && Thread.current[:connection].started?)
|
70
|
-
# p net_http_class
|
71
|
-
# net = net_http_class.new(uri.host, uri.port)
|
72
|
-
# net.use_ssl = uri.is_a?(URI::HTTPS)
|
73
|
-
# net.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
74
|
-
# Thread.current[:connection] = net
|
75
|
-
# Thread.current[:connection].start
|
76
|
-
# Thread.current[:connection]
|
77
|
-
# end
|
78
|
-
#
|
79
|
-
# def transmit(uri, req, payload)
|
80
|
-
# setup_credentials(req)
|
81
|
-
#
|
82
|
-
# Thread.current[:host] ||= uri.host
|
83
|
-
# Thread.current[:port] ||= uri.port
|
84
|
-
#
|
85
|
-
# if (Thread.current[:connection].nil? || (Thread.current[:host] != uri.host))
|
86
|
-
# p "establishing a connection"
|
87
|
-
# establish_connection(uri)
|
88
|
-
# end
|
89
|
-
#
|
90
|
-
# display_log request_log
|
91
|
-
# http = Thread.current[:connection]
|
92
|
-
# http.read_timeout = @timeout if @timeout
|
93
|
-
#
|
94
|
-
# begin
|
95
|
-
# res = http.request(req, payload)
|
96
|
-
# rescue
|
97
|
-
# p "Net::HTTP connection failed, reconnecting"
|
98
|
-
# establish_connection(uri)
|
99
|
-
# http = Thread.current[:connection]
|
100
|
-
# require 'ruby-debug'
|
101
|
-
# debugger
|
102
|
-
# req.body_stream = nil
|
103
|
-
#
|
104
|
-
# res = http.request(req, payload)
|
105
|
-
# display_log response_log(res)
|
106
|
-
# result res
|
107
|
-
# else
|
108
|
-
# display_log response_log(res)
|
109
|
-
# process_result res
|
110
|
-
# end
|
111
|
-
#
|
112
|
-
# rescue EOFError
|
113
|
-
# raise RestClient::ServerBrokeConnection
|
114
|
-
# rescue Timeout::Error
|
115
|
-
# raise RestClient::RequestTimeout
|
116
|
-
# end
|
117
|
-
# end
|
118
59
|
|
60
|
+
class Request
|
61
|
+
def transmit(uri, req, payload)
|
62
|
+
setup_credentials(req)
|
63
|
+
|
64
|
+
Thread.current[:host] ||= uri.host
|
65
|
+
Thread.current[:port] ||= uri.port
|
66
|
+
|
67
|
+
net = net_http_class.new(uri.host, uri.port)
|
68
|
+
|
69
|
+
if Thread.current[:connection].nil? || Thread.current[:host] != uri.host
|
70
|
+
Thread.current[:connection].finish if (Thread.current[:connection] && Thread.current[:connection].started?)
|
71
|
+
net.use_ssl = uri.is_a?(URI::HTTPS)
|
72
|
+
net.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
73
|
+
Thread.current[:connection] = net
|
74
|
+
Thread.current[:connection].start
|
75
|
+
end
|
76
|
+
|
77
|
+
display_log request_log
|
78
|
+
http = Thread.current[:connection]
|
79
|
+
|
80
|
+
http.read_timeout = @timeout if @timeout
|
81
|
+
begin
|
82
|
+
res = http.request(req, payload)
|
83
|
+
rescue
|
84
|
+
# p "Net::HTTP connection failed, reconnecting"
|
85
|
+
Thread.current[:connection].finish
|
86
|
+
http = Thread.current[:connection] = net
|
87
|
+
Thread.current[:connection].start
|
88
|
+
res = http.request(req, payload)
|
89
|
+
display_log response_log(res)
|
90
|
+
process_result res
|
91
|
+
else
|
92
|
+
display_log response_log(res)
|
93
|
+
process_result res
|
94
|
+
end
|
95
|
+
|
96
|
+
rescue EOFError
|
97
|
+
raise RestClient::ServerBrokeConnection
|
98
|
+
rescue Timeout::Error
|
99
|
+
raise RestClient::RequestTimeout
|
100
|
+
end
|
101
|
+
end
|
119
102
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
begin
|
2
|
-
# still required for Time parsing and pluralization in the validation
|
3
2
|
require 'extlib'
|
4
3
|
rescue
|
5
4
|
puts "CouchRest::ExtendedDocument still requires extlib (not for much longer). This is left out of the gemspec on purpose."
|
@@ -18,24 +17,18 @@ module CouchRest
|
|
18
17
|
include CouchRest::Mixins::DocumentQueries
|
19
18
|
include CouchRest::Mixins::Views
|
20
19
|
include CouchRest::Mixins::DesignDoc
|
21
|
-
include CouchRest::Mixins::ExtendedAttachments
|
22
20
|
|
23
21
|
def self.inherited(subklass)
|
24
22
|
subklass.send(:include, CouchRest::Mixins::Properties)
|
25
23
|
end
|
26
24
|
|
27
|
-
# Accessors
|
28
|
-
attr_accessor :casted_by
|
29
|
-
|
30
25
|
# Callbacks
|
31
|
-
define_callbacks :create
|
32
26
|
define_callbacks :save
|
33
|
-
define_callbacks :update
|
34
27
|
define_callbacks :destroy
|
35
28
|
|
36
|
-
def initialize(
|
37
|
-
apply_defaults # defined in CouchRest::Mixins::Properties
|
29
|
+
def initialize(keys={})
|
38
30
|
super
|
31
|
+
apply_defaults # defined in CouchRest::Mixins::Properties
|
39
32
|
cast_keys # defined in CouchRest::Mixins::Properties
|
40
33
|
unless self['_id'] && self['_rev']
|
41
34
|
self['couchrest-type'] = self.class.to_s
|
@@ -79,16 +72,6 @@ module CouchRest
|
|
79
72
|
end
|
80
73
|
end
|
81
74
|
|
82
|
-
# Temp solution to make the view_by methods available
|
83
|
-
def self.method_missing(m, *args)
|
84
|
-
if has_view?(m)
|
85
|
-
query = args.shift || {}
|
86
|
-
view(m, query, *args)
|
87
|
-
else
|
88
|
-
super
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
75
|
### instance methods
|
93
76
|
|
94
77
|
# Returns the Class properties
|
@@ -104,7 +87,7 @@ module CouchRest
|
|
104
87
|
# missing. In case of error, no attributes are changed.
|
105
88
|
def update_attributes_without_saving(hash)
|
106
89
|
hash.each do |k, v|
|
107
|
-
raise NoMethodError, "#{k}= method not available, use
|
90
|
+
raise NoMethodError, "#{k}= method not available, use key_accessor or key_writer :#{k}" unless self.respond_to?("#{k}=")
|
108
91
|
end
|
109
92
|
hash.each do |k, v|
|
110
93
|
self.send("#{k}=",v)
|
@@ -122,62 +105,12 @@ module CouchRest
|
|
122
105
|
# for compatibility with old-school frameworks
|
123
106
|
alias :new_record? :new_document?
|
124
107
|
|
125
|
-
# Trigger the callbacks (before, after, around)
|
126
|
-
# and create the document
|
127
|
-
# It's important to have a create callback since you can't check if a document
|
128
|
-
# was new after you saved it
|
129
|
-
#
|
130
|
-
# When creating a document, both the create and the save callbacks will be triggered.
|
131
|
-
def create(bulk = false)
|
132
|
-
caught = catch(:halt) do
|
133
|
-
_run_create_callbacks do
|
134
|
-
_run_save_callbacks do
|
135
|
-
create_without_callbacks(bulk)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# unlike save, create returns the newly created document
|
142
|
-
def create_without_callbacks(bulk =false)
|
143
|
-
raise ArgumentError, "a document requires a database to be created to (The document or the #{self.class} default database were not set)" unless database
|
144
|
-
set_unique_id if new_document? && self.respond_to?(:set_unique_id)
|
145
|
-
result = database.save_doc(self, bulk)
|
146
|
-
(result["ok"] == true) ? self : false
|
147
|
-
end
|
148
|
-
|
149
|
-
# Creates the document in the db. Raises an exception
|
150
|
-
# if the document is not created properly.
|
151
|
-
def create!
|
152
|
-
raise "#{self.inspect} failed to save" unless self.create
|
153
|
-
end
|
154
|
-
|
155
|
-
# Trigger the callbacks (before, after, around)
|
156
|
-
# only if the document isn't new
|
157
|
-
def update(bulk = false)
|
158
|
-
caught = catch(:halt) do
|
159
|
-
if self.new_document?
|
160
|
-
save(bulk)
|
161
|
-
else
|
162
|
-
_run_update_callbacks do
|
163
|
-
_run_save_callbacks do
|
164
|
-
save_without_callbacks(bulk)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
108
|
# Trigger the callbacks (before, after, around)
|
172
109
|
# and save the document
|
173
110
|
def save(bulk = false)
|
174
111
|
caught = catch(:halt) do
|
175
|
-
|
176
|
-
|
177
|
-
save_without_callbacks(bulk)
|
178
|
-
end
|
179
|
-
else
|
180
|
-
update(bulk)
|
112
|
+
_run_save_callbacks do
|
113
|
+
save_without_callbacks(bulk)
|
181
114
|
end
|
182
115
|
end
|
183
116
|
end
|
@@ -191,7 +124,7 @@ module CouchRest
|
|
191
124
|
result["ok"] == true
|
192
125
|
end
|
193
126
|
|
194
|
-
# Saves the document to the db using
|
127
|
+
# Saves the document to the db using create or update. Raises an exception
|
195
128
|
# if the document is not saved properly.
|
196
129
|
def save!
|
197
130
|
raise "#{self.inspect} failed to save" unless self.save
|
@@ -200,10 +133,10 @@ module CouchRest
|
|
200
133
|
# Deletes the document from the database. Runs the :destroy callbacks.
|
201
134
|
# Removes the <tt>_id</tt> and <tt>_rev</tt> fields, preparing the
|
202
135
|
# document to be saved to a new <tt>_id</tt>.
|
203
|
-
def destroy
|
136
|
+
def destroy
|
204
137
|
caught = catch(:halt) do
|
205
138
|
_run_destroy_callbacks do
|
206
|
-
result = database.delete_doc
|
139
|
+
result = database.delete_doc self
|
207
140
|
if result['ok']
|
208
141
|
self['_rev'] = nil
|
209
142
|
self['_id'] = nil
|
@@ -7,24 +7,13 @@ module CouchRest
|
|
7
7
|
# attribute to define
|
8
8
|
def initialize(name, type = nil, options = {})
|
9
9
|
@name = name.to_s
|
10
|
-
|
10
|
+
@type = type.nil? ? 'String' : type.to_s
|
11
11
|
parse_options(options)
|
12
12
|
self
|
13
13
|
end
|
14
14
|
|
15
15
|
|
16
16
|
private
|
17
|
-
|
18
|
-
def parse_type(type)
|
19
|
-
if type.nil?
|
20
|
-
@type = 'String'
|
21
|
-
elsif type.is_a?(Array) && type.empty?
|
22
|
-
@type = 'Array'
|
23
|
-
else
|
24
|
-
@type = type.is_a?(Array) ? [type.first.to_s] : type.to_s
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
17
|
def parse_options(options)
|
29
18
|
return if options.empty?
|
30
19
|
@validation_format = options.delete(:format) if options[:format]
|