ripple 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +61 -48
- data/lib/ripple.rb +5 -1
- data/lib/ripple/core_ext/casting.rb +3 -0
- data/lib/ripple/document.rb +6 -2
- data/lib/ripple/document/associations.rb +154 -0
- data/lib/ripple/document/{persistence/callbacks.rb → associations/embedded.rb} +20 -24
- data/lib/ripple/document/associations/instantiators.rb +41 -0
- data/lib/{riak/util/translation.rb → ripple/document/associations/linked.rb} +14 -11
- data/lib/ripple/document/associations/many.rb +52 -0
- data/lib/ripple/document/associations/many_embedded_proxy.rb +49 -0
- data/lib/{riak/i18n.rb → ripple/document/associations/one.rb} +18 -2
- data/lib/ripple/document/associations/one_embedded_proxy.rb +41 -0
- data/lib/ripple/document/associations/proxy.rb +125 -0
- data/lib/ripple/document/attribute_methods.rb +8 -1
- data/lib/ripple/document/attribute_methods/read.rb +4 -0
- data/lib/ripple/document/attribute_methods/write.rb +4 -0
- data/lib/ripple/document/bucket_access.rb +1 -1
- data/lib/ripple/document/callbacks.rb +75 -0
- data/lib/ripple/document/finders.rb +50 -3
- data/lib/ripple/document/persistence.rb +14 -6
- data/lib/ripple/document/validations.rb +35 -7
- data/lib/ripple/document/validations/associated_validator.rb +37 -0
- data/lib/ripple/embedded_document.rb +8 -2
- data/lib/{riak/map_reduce_error.rb → ripple/embedded_document/conversion.rb} +19 -5
- data/lib/{riak/invalid_response.rb → ripple/embedded_document/finders.rb} +17 -8
- data/lib/ripple/embedded_document/persistence.rb +75 -13
- data/lib/ripple/locale/en.yml +7 -1
- data/{spec/riak/net_http_backend_spec.rb → lib/ripple/railtie.rb} +17 -13
- data/spec/fixtures/config.yml +3 -0
- data/spec/integration/ripple/associations_spec.rb +81 -0
- data/spec/integration/ripple/persistence_spec.rb +54 -0
- data/spec/ripple/associations/many_embedded_proxy_spec.rb +124 -0
- data/spec/ripple/associations/one_embedded_proxy_spec.rb +130 -0
- data/spec/ripple/associations/proxy_spec.rb +78 -0
- data/spec/ripple/associations_spec.rb +111 -0
- data/spec/ripple/attribute_methods_spec.rb +37 -16
- data/spec/ripple/bucket_access_spec.rb +3 -14
- data/spec/ripple/callbacks_spec.rb +53 -9
- data/spec/ripple/document_spec.rb +22 -6
- data/spec/ripple/embedded_document/conversion_spec.rb +35 -0
- data/spec/{riak/headers_spec.rb → ripple/embedded_document/finders_spec.rb} +17 -14
- data/spec/ripple/embedded_document/persistence_spec.rb +86 -0
- data/spec/ripple/embedded_document_spec.rb +1 -26
- data/spec/ripple/finders_spec.rb +66 -30
- data/spec/ripple/persistence_spec.rb +33 -21
- data/spec/ripple/properties_spec.rb +1 -7
- data/spec/ripple/ripple_spec.rb +10 -0
- data/spec/ripple/timestamps_spec.rb +12 -19
- data/spec/ripple/validations_spec.rb +48 -6
- data/spec/spec_helper.rb +4 -10
- data/spec/support/associations/proxies.rb +16 -0
- data/spec/support/integration.rb +4 -0
- data/spec/support/mocks.rb +3 -0
- data/spec/support/models/address.rb +8 -0
- data/spec/support/models/box.rb +6 -0
- data/spec/support/models/cardboard_box.rb +3 -0
- data/spec/support/models/clock.rb +6 -0
- data/spec/support/models/customer.rb +4 -0
- data/spec/support/models/email.rb +4 -0
- data/spec/support/models/family.rb +14 -0
- data/spec/support/models/favorite.rb +4 -0
- data/spec/support/models/invoice.rb +6 -0
- data/spec/support/models/late_invoice.rb +3 -0
- data/spec/support/models/note.rb +4 -0
- data/spec/support/models/page.rb +4 -0
- data/spec/support/models/paid_invoice.rb +4 -0
- data/spec/support/models/tree.rb +3 -0
- data/spec/support/models/user.rb +6 -0
- data/spec/support/models/widget.rb +6 -0
- metadata +111 -138
- data/.document +0 -5
- data/.gitignore +0 -26
- data/CONTRIBUTORS.textile +0 -5
- data/LICENSE +0 -13
- data/README.textile +0 -128
- data/RELEASE_NOTES.textile +0 -68
- data/VERSION +0 -1
- data/lib/riak.rb +0 -46
- data/lib/riak/bucket.rb +0 -157
- data/lib/riak/client.rb +0 -139
- data/lib/riak/client/curb_backend.rb +0 -82
- data/lib/riak/client/http_backend.rb +0 -209
- data/lib/riak/client/net_http_backend.rb +0 -49
- data/lib/riak/failed_request.rb +0 -37
- data/lib/riak/link.rb +0 -73
- data/lib/riak/locale/en.yml +0 -37
- data/lib/riak/map_reduce.rb +0 -248
- data/lib/riak/robject.rb +0 -258
- data/lib/riak/util/escape.rb +0 -12
- data/lib/riak/util/fiber1.8.rb +0 -48
- data/lib/riak/util/headers.rb +0 -44
- data/lib/riak/util/multipart.rb +0 -52
- data/lib/riak/walk_spec.rb +0 -117
- data/ripple.gemspec +0 -169
- data/spec/fixtures/cat.jpg +0 -0
- data/spec/fixtures/multipart-blank.txt +0 -7
- data/spec/fixtures/multipart-with-body.txt +0 -16
- data/spec/riak/bucket_spec.rb +0 -230
- data/spec/riak/client_spec.rb +0 -174
- data/spec/riak/curb_backend_spec.rb +0 -50
- data/spec/riak/escape_spec.rb +0 -17
- data/spec/riak/http_backend_spec.rb +0 -131
- data/spec/riak/link_spec.rb +0 -82
- data/spec/riak/map_reduce_spec.rb +0 -352
- data/spec/riak/multipart_spec.rb +0 -36
- data/spec/riak/object_spec.rb +0 -532
- data/spec/riak/walk_spec_spec.rb +0 -208
- data/spec/spec.opts +0 -1
- data/spec/support/http_backend_implementation_examples.rb +0 -215
- data/spec/support/mock_server.rb +0 -58
@@ -0,0 +1,52 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require 'ripple'
|
15
|
+
|
16
|
+
module Ripple
|
17
|
+
module Document
|
18
|
+
module Associations
|
19
|
+
module Many
|
20
|
+
include Instantiators
|
21
|
+
|
22
|
+
def to_ary
|
23
|
+
load_target
|
24
|
+
Array === target ? target.to_ary : Array(target)
|
25
|
+
end
|
26
|
+
|
27
|
+
def count
|
28
|
+
load_target
|
29
|
+
target.size
|
30
|
+
end
|
31
|
+
|
32
|
+
def reset
|
33
|
+
super
|
34
|
+
@target = []
|
35
|
+
end
|
36
|
+
|
37
|
+
def <<
|
38
|
+
raise NotImplementedError
|
39
|
+
end
|
40
|
+
alias_method :push, :<<
|
41
|
+
alias_method :concat, :<<
|
42
|
+
|
43
|
+
protected
|
44
|
+
def instantiate_target(instantiator, attrs={})
|
45
|
+
doc = klass.send(instantiator, attrs)
|
46
|
+
self << doc
|
47
|
+
doc
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require 'ripple'
|
15
|
+
|
16
|
+
module Ripple
|
17
|
+
module Document
|
18
|
+
module Associations
|
19
|
+
class ManyEmbeddedProxy < Proxy
|
20
|
+
include Many
|
21
|
+
include Embedded
|
22
|
+
|
23
|
+
def <<(docs)
|
24
|
+
load_target
|
25
|
+
assign_references(docs)
|
26
|
+
@target += Array(docs)
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def replace(docs)
|
31
|
+
@_docs = docs.map { |doc| attrs = doc.respond_to?(:attributes_for_persistence) ? doc.attributes_for_persistence : doc }
|
32
|
+
assign_references(docs)
|
33
|
+
reset
|
34
|
+
@_docs
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
def find_target
|
39
|
+
(@_docs || []).map do |attrs|
|
40
|
+
klass.instantiate(attrs).tap do |doc|
|
41
|
+
assign_references(doc)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -11,5 +11,21 @@
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
|
-
require '
|
15
|
-
|
14
|
+
require 'ripple'
|
15
|
+
|
16
|
+
module Ripple
|
17
|
+
module Document
|
18
|
+
module Associations
|
19
|
+
module One
|
20
|
+
include Instantiators
|
21
|
+
|
22
|
+
protected
|
23
|
+
def instantiate_target(instantiator, attrs={})
|
24
|
+
@target = klass.send(instantiator, attrs)
|
25
|
+
loaded
|
26
|
+
@target
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require 'ripple'
|
15
|
+
|
16
|
+
module Ripple
|
17
|
+
module Document
|
18
|
+
module Associations
|
19
|
+
class OneEmbeddedProxy < Proxy
|
20
|
+
include One
|
21
|
+
include Embedded
|
22
|
+
|
23
|
+
def replace(doc)
|
24
|
+
@_doc = doc.respond_to?(:attributes_for_persistence) ? doc.attributes_for_persistence : doc
|
25
|
+
assign_references(doc)
|
26
|
+
reset
|
27
|
+
@_doc
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
def find_target
|
32
|
+
return nil unless @_doc
|
33
|
+
klass.instantiate(@_doc).tap do |doc|
|
34
|
+
assign_references(doc)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require 'ripple'
|
15
|
+
|
16
|
+
module Ripple
|
17
|
+
module Document
|
18
|
+
module Associations
|
19
|
+
class Proxy
|
20
|
+
alias :proxy_respond_to? :respond_to?
|
21
|
+
alias :proxy_extend :extend
|
22
|
+
|
23
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
|
24
|
+
|
25
|
+
attr_reader :owner, :reflection, :target
|
26
|
+
|
27
|
+
alias :proxy_owner :owner
|
28
|
+
alias :proxy_target :target
|
29
|
+
alias :proxy_reflection :reflection
|
30
|
+
|
31
|
+
delegate :klass, :to => :proxy_reflection
|
32
|
+
delegate :options, :to => :proxy_reflection
|
33
|
+
delegate :collection, :to => :klass
|
34
|
+
|
35
|
+
def initialize(owner, reflection)
|
36
|
+
@owner, @reflection = owner, reflection
|
37
|
+
Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
|
38
|
+
reset
|
39
|
+
end
|
40
|
+
|
41
|
+
def inspect
|
42
|
+
load_target
|
43
|
+
target.inspect
|
44
|
+
end
|
45
|
+
|
46
|
+
def loaded?
|
47
|
+
@loaded
|
48
|
+
end
|
49
|
+
|
50
|
+
def loaded
|
51
|
+
@loaded = true
|
52
|
+
end
|
53
|
+
|
54
|
+
def nil?
|
55
|
+
load_target
|
56
|
+
target.nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
def blank?
|
60
|
+
load_target
|
61
|
+
target.blank?
|
62
|
+
end
|
63
|
+
|
64
|
+
def present?
|
65
|
+
load_target
|
66
|
+
target.present?
|
67
|
+
end
|
68
|
+
|
69
|
+
def reload
|
70
|
+
reset
|
71
|
+
load_target
|
72
|
+
self unless target.nil?
|
73
|
+
end
|
74
|
+
|
75
|
+
def replace(v)
|
76
|
+
raise NotImplementedError
|
77
|
+
end
|
78
|
+
|
79
|
+
def reset
|
80
|
+
@loaded = false
|
81
|
+
@target = nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def respond_to?(*args)
|
85
|
+
proxy_respond_to?(*args) || (load_target && target.respond_to?(*args))
|
86
|
+
end
|
87
|
+
|
88
|
+
def send(method, *args, &block)
|
89
|
+
if proxy_respond_to?(method)
|
90
|
+
super
|
91
|
+
else
|
92
|
+
load_target
|
93
|
+
target.send(method, *args, &block)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def ===(other)
|
98
|
+
load_target
|
99
|
+
other === target
|
100
|
+
end
|
101
|
+
|
102
|
+
protected
|
103
|
+
def method_missing(method, *args, &block)
|
104
|
+
if load_target
|
105
|
+
if block_given?
|
106
|
+
target.send(method, *args) { |*block_args| block.call(*block_args) }
|
107
|
+
else
|
108
|
+
target.send(method, *args)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def load_target
|
114
|
+
@target = find_target unless loaded?
|
115
|
+
loaded
|
116
|
+
@target
|
117
|
+
end
|
118
|
+
|
119
|
+
def find_target
|
120
|
+
raise NotImplementedError
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -28,7 +28,6 @@ module Ripple
|
|
28
28
|
autoload :Dirty
|
29
29
|
|
30
30
|
included do
|
31
|
-
attr_accessor :key
|
32
31
|
include Read
|
33
32
|
include Write
|
34
33
|
include Query
|
@@ -50,6 +49,8 @@ module Ripple
|
|
50
49
|
end
|
51
50
|
|
52
51
|
module InstanceMethods
|
52
|
+
attr_accessor :key
|
53
|
+
|
53
54
|
# A copy of the values of all attributes in the Document. The result
|
54
55
|
# is not memoized, so use sparingly. This does not include associated objects,
|
55
56
|
# nor embedded documents.
|
@@ -66,6 +67,7 @@ module Ripple
|
|
66
67
|
def attributes=(attrs)
|
67
68
|
raise ArgumentError, t('attribute_hash') unless Hash === attrs
|
68
69
|
attrs.each do |k,v|
|
70
|
+
next if k.to_sym == :key
|
69
71
|
if respond_to?("#{k}=")
|
70
72
|
__send__("#{k}=",v)
|
71
73
|
else
|
@@ -73,12 +75,17 @@ module Ripple
|
|
73
75
|
end
|
74
76
|
end
|
75
77
|
end
|
78
|
+
|
79
|
+
def key=(value)
|
80
|
+
@key = value.to_s
|
81
|
+
end
|
76
82
|
|
77
83
|
# @private
|
78
84
|
def initialize(attrs={})
|
79
85
|
super()
|
80
86
|
@attributes = attributes_from_property_defaults
|
81
87
|
self.attributes = attrs
|
88
|
+
yield self if block_given?
|
82
89
|
end
|
83
90
|
|
84
91
|
# @private
|
@@ -31,7 +31,7 @@ module Ripple
|
|
31
31
|
# Set the bucket name for this class and its subclasses.
|
32
32
|
# @param [String] value the new bucket name
|
33
33
|
def bucket_name=(value)
|
34
|
-
|
34
|
+
(class << self; self; end).send(:define_method, :bucket_name){ value }
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require 'ripple'
|
15
|
+
|
16
|
+
module Ripple
|
17
|
+
module Document
|
18
|
+
module Callbacks
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
|
21
|
+
included do
|
22
|
+
extend ActiveModel::Callbacks
|
23
|
+
define_model_callbacks :create, :update, :save, :destroy
|
24
|
+
define_callbacks :validation, :terminator => "result == false", :scope => [:kind, :name]
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
def before_validation(*args, &block)
|
29
|
+
options = args.last
|
30
|
+
if options.is_a?(Hash) && options[:on]
|
31
|
+
options[:if] = Array(options[:if])
|
32
|
+
options[:if] << "@_on_validate == :#{options[:on]}"
|
33
|
+
end
|
34
|
+
set_callback(:validation, :before, *args, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def after_validation(*args, &block)
|
38
|
+
options = args.extract_options!
|
39
|
+
options[:prepend] = true
|
40
|
+
options[:if] = Array(options[:if])
|
41
|
+
options[:if] << "!halted && value != false"
|
42
|
+
options[:if] << "@_on_validate == :#{options[:on]}" if options[:on]
|
43
|
+
set_callback(:validation, :after, *(args << options), &block)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
module InstanceMethods
|
48
|
+
# @private
|
49
|
+
def save(*args, &block)
|
50
|
+
state = new? ? :create : :update
|
51
|
+
run_callbacks(:save) do
|
52
|
+
run_callbacks(state) do
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# @private
|
59
|
+
def destroy(*args, &block)
|
60
|
+
run_callbacks(:destroy) do
|
61
|
+
super
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# @private
|
66
|
+
def valid?(*args, &block)
|
67
|
+
@_on_validate = new? ? :create : :update
|
68
|
+
run_callbacks(:validation) do
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|