ripple 0.7.0 → 0.7.1
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/lib/ripple.rb +17 -1
- data/lib/ripple/associations.rb +157 -0
- data/lib/ripple/associations/embedded.rb +42 -0
- data/lib/ripple/associations/instantiators.rb +39 -0
- data/lib/ripple/{document/associations → associations}/linked.rb +9 -11
- data/lib/ripple/{document/associations/one_embedded_proxy.rb → associations/many.rb} +30 -21
- data/lib/ripple/{document/associations/embedded.rb → associations/many_embedded_proxy.rb} +26 -23
- data/lib/ripple/{embedded_document/conversion.rb → associations/one.rb} +8 -13
- data/lib/ripple/{document/associations/instantiators.rb → associations/one_embedded_proxy.rb} +17 -19
- data/lib/ripple/associations/proxy.rb +123 -0
- data/lib/ripple/attribute_methods.rb +116 -0
- data/lib/ripple/{document/attribute_methods/write.rb → attribute_methods/dirty.rb} +26 -16
- data/lib/ripple/attribute_methods/query.rb +48 -0
- data/lib/ripple/{document/attribute_methods → attribute_methods}/read.rb +16 -18
- data/lib/ripple/attribute_methods/write.rb +38 -0
- data/lib/ripple/callbacks.rb +73 -0
- data/lib/ripple/{document/associations/one.rb → conversion.rb} +18 -13
- data/lib/ripple/document.rb +19 -9
- data/lib/ripple/embedded_document.rb +10 -10
- data/lib/ripple/embedded_document/persistence.rb +12 -53
- data/lib/ripple/properties.rb +83 -0
- data/lib/ripple/timestamps.rb +34 -0
- data/lib/ripple/{document/validations.rb → validations.rb} +31 -33
- data/lib/ripple/{document/validations → validations}/associated_validator.rb +9 -10
- data/spec/integration/ripple/associations_spec.rb +1 -2
- data/spec/integration/ripple/persistence_spec.rb +2 -3
- data/spec/ripple/associations/many_embedded_proxy_spec.rb +2 -2
- data/spec/ripple/associations/one_embedded_proxy_spec.rb +2 -2
- data/spec/ripple/associations/proxy_spec.rb +1 -1
- data/spec/ripple/associations_spec.rb +15 -20
- data/spec/ripple/attribute_methods_spec.rb +3 -6
- data/spec/ripple/callbacks_spec.rb +1 -1
- data/spec/ripple/{embedded_document/conversion_spec.rb → conversion_spec.rb} +4 -4
- data/spec/ripple/embedded_document/persistence_spec.rb +4 -16
- data/spec/ripple/properties_spec.rb +17 -18
- data/spec/ripple/timestamps_spec.rb +1 -1
- data/spec/ripple/validations_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/associations/proxies.rb +4 -4
- metadata +27 -29
- data/lib/ripple/document/associations.rb +0 -154
- data/lib/ripple/document/associations/many.rb +0 -52
- data/lib/ripple/document/associations/many_embedded_proxy.rb +0 -49
- data/lib/ripple/document/associations/proxy.rb +0 -125
- data/lib/ripple/document/attribute_methods.rb +0 -118
- data/lib/ripple/document/attribute_methods/dirty.rb +0 -52
- data/lib/ripple/document/attribute_methods/query.rb +0 -49
- data/lib/ripple/document/callbacks.rb +0 -75
- data/lib/ripple/document/properties.rb +0 -85
- data/lib/ripple/document/timestamps.rb +0 -22
- data/spec/support/integration.rb +0 -4
data/lib/ripple/{document/associations/instantiators.rb → associations/one_embedded_proxy.rb}
RENAMED
@@ -14,28 +14,26 @@
|
|
14
14
|
require 'ripple'
|
15
15
|
|
16
16
|
module Ripple
|
17
|
-
module
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def build(attrs={})
|
22
|
-
instantiate_target(:new, attrs)
|
23
|
-
end
|
17
|
+
module Associations
|
18
|
+
class OneEmbeddedProxy < Proxy
|
19
|
+
include One
|
20
|
+
include Embedded
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
def replace(doc)
|
23
|
+
@_doc = doc.respond_to?(:attributes_for_persistence) ? doc.attributes_for_persistence : doc
|
24
|
+
assign_references(doc)
|
25
|
+
reset
|
26
|
+
@_doc
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
protected
|
30
|
+
def find_target
|
31
|
+
return nil unless @_doc
|
32
|
+
klass.instantiate(@_doc).tap do |doc|
|
33
|
+
assign_references(doc)
|
31
34
|
end
|
32
|
-
|
33
|
-
protected
|
34
|
-
def instantiate_target
|
35
|
-
raise NotImplementedError
|
36
|
-
end
|
37
|
-
|
38
35
|
end
|
36
|
+
|
39
37
|
end
|
40
38
|
end
|
41
|
-
end
|
39
|
+
end
|
@@ -0,0 +1,123 @@
|
|
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 Associations
|
18
|
+
class Proxy
|
19
|
+
alias :proxy_respond_to? :respond_to?
|
20
|
+
alias :proxy_extend :extend
|
21
|
+
|
22
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
|
23
|
+
|
24
|
+
attr_reader :owner, :reflection, :target
|
25
|
+
|
26
|
+
alias :proxy_owner :owner
|
27
|
+
alias :proxy_target :target
|
28
|
+
alias :proxy_reflection :reflection
|
29
|
+
|
30
|
+
delegate :klass, :to => :proxy_reflection
|
31
|
+
delegate :options, :to => :proxy_reflection
|
32
|
+
delegate :collection, :to => :klass
|
33
|
+
|
34
|
+
def initialize(owner, reflection)
|
35
|
+
@owner, @reflection = owner, reflection
|
36
|
+
Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
|
37
|
+
reset
|
38
|
+
end
|
39
|
+
|
40
|
+
def inspect
|
41
|
+
load_target
|
42
|
+
target.inspect
|
43
|
+
end
|
44
|
+
|
45
|
+
def loaded?
|
46
|
+
@loaded
|
47
|
+
end
|
48
|
+
|
49
|
+
def loaded
|
50
|
+
@loaded = true
|
51
|
+
end
|
52
|
+
|
53
|
+
def nil?
|
54
|
+
load_target
|
55
|
+
target.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
def blank?
|
59
|
+
load_target
|
60
|
+
target.blank?
|
61
|
+
end
|
62
|
+
|
63
|
+
def present?
|
64
|
+
load_target
|
65
|
+
target.present?
|
66
|
+
end
|
67
|
+
|
68
|
+
def reload
|
69
|
+
reset
|
70
|
+
load_target
|
71
|
+
self unless target.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
def replace(v)
|
75
|
+
raise NotImplementedError
|
76
|
+
end
|
77
|
+
|
78
|
+
def reset
|
79
|
+
@loaded = false
|
80
|
+
@target = nil
|
81
|
+
end
|
82
|
+
|
83
|
+
def respond_to?(*args)
|
84
|
+
proxy_respond_to?(*args) || (load_target && target.respond_to?(*args))
|
85
|
+
end
|
86
|
+
|
87
|
+
def send(method, *args, &block)
|
88
|
+
if proxy_respond_to?(method)
|
89
|
+
super
|
90
|
+
else
|
91
|
+
load_target
|
92
|
+
target.send(method, *args, &block)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def ===(other)
|
97
|
+
load_target
|
98
|
+
other === target
|
99
|
+
end
|
100
|
+
|
101
|
+
protected
|
102
|
+
def method_missing(method, *args, &block)
|
103
|
+
if load_target
|
104
|
+
if block_given?
|
105
|
+
target.send(method, *args) { |*block_args| block.call(*block_args) }
|
106
|
+
else
|
107
|
+
target.send(method, *args)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def load_target
|
113
|
+
@target = find_target unless loaded?
|
114
|
+
loaded
|
115
|
+
@target
|
116
|
+
end
|
117
|
+
|
118
|
+
def find_target
|
119
|
+
raise NotImplementedError
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,116 @@
|
|
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
|
+
# Makes ActiveRecord-like attribute accessors based on your
|
18
|
+
# {Document}'s properties.
|
19
|
+
module AttributeMethods
|
20
|
+
extend ActiveSupport::Concern
|
21
|
+
extend ActiveSupport::Autoload
|
22
|
+
include ActiveModel::AttributeMethods
|
23
|
+
|
24
|
+
autoload :Read
|
25
|
+
autoload :Write
|
26
|
+
autoload :Query
|
27
|
+
autoload :Dirty
|
28
|
+
|
29
|
+
included do
|
30
|
+
include Read
|
31
|
+
include Write
|
32
|
+
include Query
|
33
|
+
include Dirty
|
34
|
+
end
|
35
|
+
|
36
|
+
module ClassMethods
|
37
|
+
# @private
|
38
|
+
def property(key, type, options={})
|
39
|
+
undefine_attribute_methods
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
# Generates all the attribute-related methods for properties defined
|
44
|
+
# on the document, including accessors, mutators and query methods.
|
45
|
+
def define_attribute_methods
|
46
|
+
super(properties.keys)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module InstanceMethods
|
51
|
+
attr_accessor :key
|
52
|
+
|
53
|
+
# A copy of the values of all attributes in the Document. The result
|
54
|
+
# is not memoized, so use sparingly. This does not include associated objects,
|
55
|
+
# nor embedded documents.
|
56
|
+
# @return [Hash] all document attributes, by key
|
57
|
+
def attributes
|
58
|
+
self.class.properties.values.inject({}) do |hash, prop|
|
59
|
+
hash[prop.key] = attribute(prop.key)
|
60
|
+
hash
|
61
|
+
end.with_indifferent_access
|
62
|
+
end
|
63
|
+
|
64
|
+
# Mass assign the document's attributes.
|
65
|
+
# @param [Hash] attrs the attributes to assign
|
66
|
+
def attributes=(attrs)
|
67
|
+
raise ArgumentError, t('attribute_hash') unless Hash === attrs
|
68
|
+
attrs.each do |k,v|
|
69
|
+
next if k.to_sym == :key
|
70
|
+
if respond_to?("#{k}=")
|
71
|
+
__send__("#{k}=",v)
|
72
|
+
else
|
73
|
+
__send__(:attribute=,k,v)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def key=(value)
|
79
|
+
@key = value.to_s
|
80
|
+
end
|
81
|
+
|
82
|
+
# @private
|
83
|
+
def initialize(attrs={})
|
84
|
+
super()
|
85
|
+
@attributes = attributes_from_property_defaults
|
86
|
+
self.attributes = attrs
|
87
|
+
yield self if block_given?
|
88
|
+
end
|
89
|
+
|
90
|
+
# @private
|
91
|
+
def method_missing(method, *args, &block)
|
92
|
+
self.class.define_attribute_methods
|
93
|
+
super
|
94
|
+
end
|
95
|
+
|
96
|
+
# @private
|
97
|
+
def respond_to?(*args)
|
98
|
+
self.class.define_attribute_methods
|
99
|
+
super
|
100
|
+
end
|
101
|
+
|
102
|
+
protected
|
103
|
+
# @private
|
104
|
+
def attribute_method?(attr_name)
|
105
|
+
self.class.properties.include?(attr_name)
|
106
|
+
end
|
107
|
+
|
108
|
+
def attributes_from_property_defaults
|
109
|
+
self.class.properties.values.inject({}) do |hash, prop|
|
110
|
+
hash[prop.key] = prop.default if prop.default
|
111
|
+
hash
|
112
|
+
end.with_indifferent_access
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -14,27 +14,37 @@
|
|
14
14
|
require 'ripple'
|
15
15
|
|
16
16
|
module Ripple
|
17
|
-
module
|
18
|
-
module
|
19
|
-
|
20
|
-
|
17
|
+
module AttributeMethods
|
18
|
+
module Dirty
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
include ActiveModel::Dirty
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
def []=(attr_name, value)
|
27
|
-
__send__(:attribute=, attr_name, value)
|
22
|
+
# @private
|
23
|
+
def save
|
24
|
+
if result = super
|
25
|
+
changed_attributes.clear
|
28
26
|
end
|
27
|
+
result
|
28
|
+
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
@attributes[attr_name] = value
|
30
|
+
# @private
|
31
|
+
def reload
|
32
|
+
returning super do
|
33
|
+
changed_attributes.clear
|
36
34
|
end
|
37
35
|
end
|
36
|
+
|
37
|
+
# @private
|
38
|
+
def initialize(attrs={})
|
39
|
+
super(attrs)
|
40
|
+
changed_attributes.clear
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def attribute=(attr_name, value)
|
45
|
+
attribute_will_change!(attr_name)
|
46
|
+
super
|
47
|
+
end
|
38
48
|
end
|
39
49
|
end
|
40
50
|
end
|
@@ -0,0 +1,48 @@
|
|
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
|
+
|
18
|
+
module AttributeMethods
|
19
|
+
module Query
|
20
|
+
extend ActiveSupport::Concern
|
21
|
+
|
22
|
+
included do
|
23
|
+
attribute_method_suffix "?"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
# Based on code from ActiveRecord
|
28
|
+
def attribute?(attr_name)
|
29
|
+
unless value = attribute(attr_name)
|
30
|
+
false
|
31
|
+
else
|
32
|
+
prop = self.class.properties[attr_name]
|
33
|
+
if prop.nil?
|
34
|
+
if Numeric === value || value !~ /[^0-9]/
|
35
|
+
!value.to_i.zero?
|
36
|
+
else
|
37
|
+
Boolean.ripple_cast(value) || value.present?
|
38
|
+
end
|
39
|
+
elsif prop.type <= Numeric
|
40
|
+
!value.zero?
|
41
|
+
else
|
42
|
+
value.present?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -14,26 +14,24 @@
|
|
14
14
|
require 'ripple'
|
15
15
|
|
16
16
|
module Ripple
|
17
|
-
module
|
18
|
-
module
|
19
|
-
|
20
|
-
extend ActiveSupport::Concern
|
17
|
+
module AttributeMethods
|
18
|
+
module Read
|
19
|
+
extend ActiveSupport::Concern
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
included do
|
22
|
+
attribute_method_suffix ""
|
23
|
+
end
|
24
|
+
|
25
|
+
def [](attr_name)
|
26
|
+
attribute(attr_name)
|
27
|
+
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
29
|
+
private
|
30
|
+
def attribute(attr_name)
|
31
|
+
if @attributes.include?(attr_name)
|
32
|
+
@attributes[attr_name]
|
33
|
+
else
|
34
|
+
nil
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
@@ -0,0 +1,38 @@
|
|
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 AttributeMethods
|
18
|
+
module Write
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
|
21
|
+
included do
|
22
|
+
attribute_method_suffix "="
|
23
|
+
end
|
24
|
+
|
25
|
+
def []=(attr_name, value)
|
26
|
+
__send__(:attribute=, attr_name, value)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def attribute=(attr_name, value)
|
31
|
+
if prop = self.class.properties[attr_name]
|
32
|
+
value = prop.type_cast(value)
|
33
|
+
end
|
34
|
+
@attributes[attr_name] = value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|