ripple 0.6.1 → 0.7.0

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.
Files changed (110) hide show
  1. data/Rakefile +61 -48
  2. data/lib/ripple.rb +5 -1
  3. data/lib/ripple/core_ext/casting.rb +3 -0
  4. data/lib/ripple/document.rb +6 -2
  5. data/lib/ripple/document/associations.rb +154 -0
  6. data/lib/ripple/document/{persistence/callbacks.rb → associations/embedded.rb} +20 -24
  7. data/lib/ripple/document/associations/instantiators.rb +41 -0
  8. data/lib/{riak/util/translation.rb → ripple/document/associations/linked.rb} +14 -11
  9. data/lib/ripple/document/associations/many.rb +52 -0
  10. data/lib/ripple/document/associations/many_embedded_proxy.rb +49 -0
  11. data/lib/{riak/i18n.rb → ripple/document/associations/one.rb} +18 -2
  12. data/lib/ripple/document/associations/one_embedded_proxy.rb +41 -0
  13. data/lib/ripple/document/associations/proxy.rb +125 -0
  14. data/lib/ripple/document/attribute_methods.rb +8 -1
  15. data/lib/ripple/document/attribute_methods/read.rb +4 -0
  16. data/lib/ripple/document/attribute_methods/write.rb +4 -0
  17. data/lib/ripple/document/bucket_access.rb +1 -1
  18. data/lib/ripple/document/callbacks.rb +75 -0
  19. data/lib/ripple/document/finders.rb +50 -3
  20. data/lib/ripple/document/persistence.rb +14 -6
  21. data/lib/ripple/document/validations.rb +35 -7
  22. data/lib/ripple/document/validations/associated_validator.rb +37 -0
  23. data/lib/ripple/embedded_document.rb +8 -2
  24. data/lib/{riak/map_reduce_error.rb → ripple/embedded_document/conversion.rb} +19 -5
  25. data/lib/{riak/invalid_response.rb → ripple/embedded_document/finders.rb} +17 -8
  26. data/lib/ripple/embedded_document/persistence.rb +75 -13
  27. data/lib/ripple/locale/en.yml +7 -1
  28. data/{spec/riak/net_http_backend_spec.rb → lib/ripple/railtie.rb} +17 -13
  29. data/spec/fixtures/config.yml +3 -0
  30. data/spec/integration/ripple/associations_spec.rb +81 -0
  31. data/spec/integration/ripple/persistence_spec.rb +54 -0
  32. data/spec/ripple/associations/many_embedded_proxy_spec.rb +124 -0
  33. data/spec/ripple/associations/one_embedded_proxy_spec.rb +130 -0
  34. data/spec/ripple/associations/proxy_spec.rb +78 -0
  35. data/spec/ripple/associations_spec.rb +111 -0
  36. data/spec/ripple/attribute_methods_spec.rb +37 -16
  37. data/spec/ripple/bucket_access_spec.rb +3 -14
  38. data/spec/ripple/callbacks_spec.rb +53 -9
  39. data/spec/ripple/document_spec.rb +22 -6
  40. data/spec/ripple/embedded_document/conversion_spec.rb +35 -0
  41. data/spec/{riak/headers_spec.rb → ripple/embedded_document/finders_spec.rb} +17 -14
  42. data/spec/ripple/embedded_document/persistence_spec.rb +86 -0
  43. data/spec/ripple/embedded_document_spec.rb +1 -26
  44. data/spec/ripple/finders_spec.rb +66 -30
  45. data/spec/ripple/persistence_spec.rb +33 -21
  46. data/spec/ripple/properties_spec.rb +1 -7
  47. data/spec/ripple/ripple_spec.rb +10 -0
  48. data/spec/ripple/timestamps_spec.rb +12 -19
  49. data/spec/ripple/validations_spec.rb +48 -6
  50. data/spec/spec_helper.rb +4 -10
  51. data/spec/support/associations/proxies.rb +16 -0
  52. data/spec/support/integration.rb +4 -0
  53. data/spec/support/mocks.rb +3 -0
  54. data/spec/support/models/address.rb +8 -0
  55. data/spec/support/models/box.rb +6 -0
  56. data/spec/support/models/cardboard_box.rb +3 -0
  57. data/spec/support/models/clock.rb +6 -0
  58. data/spec/support/models/customer.rb +4 -0
  59. data/spec/support/models/email.rb +4 -0
  60. data/spec/support/models/family.rb +14 -0
  61. data/spec/support/models/favorite.rb +4 -0
  62. data/spec/support/models/invoice.rb +6 -0
  63. data/spec/support/models/late_invoice.rb +3 -0
  64. data/spec/support/models/note.rb +4 -0
  65. data/spec/support/models/page.rb +4 -0
  66. data/spec/support/models/paid_invoice.rb +4 -0
  67. data/spec/support/models/tree.rb +3 -0
  68. data/spec/support/models/user.rb +6 -0
  69. data/spec/support/models/widget.rb +6 -0
  70. metadata +111 -138
  71. data/.document +0 -5
  72. data/.gitignore +0 -26
  73. data/CONTRIBUTORS.textile +0 -5
  74. data/LICENSE +0 -13
  75. data/README.textile +0 -128
  76. data/RELEASE_NOTES.textile +0 -68
  77. data/VERSION +0 -1
  78. data/lib/riak.rb +0 -46
  79. data/lib/riak/bucket.rb +0 -157
  80. data/lib/riak/client.rb +0 -139
  81. data/lib/riak/client/curb_backend.rb +0 -82
  82. data/lib/riak/client/http_backend.rb +0 -209
  83. data/lib/riak/client/net_http_backend.rb +0 -49
  84. data/lib/riak/failed_request.rb +0 -37
  85. data/lib/riak/link.rb +0 -73
  86. data/lib/riak/locale/en.yml +0 -37
  87. data/lib/riak/map_reduce.rb +0 -248
  88. data/lib/riak/robject.rb +0 -258
  89. data/lib/riak/util/escape.rb +0 -12
  90. data/lib/riak/util/fiber1.8.rb +0 -48
  91. data/lib/riak/util/headers.rb +0 -44
  92. data/lib/riak/util/multipart.rb +0 -52
  93. data/lib/riak/walk_spec.rb +0 -117
  94. data/ripple.gemspec +0 -169
  95. data/spec/fixtures/cat.jpg +0 -0
  96. data/spec/fixtures/multipart-blank.txt +0 -7
  97. data/spec/fixtures/multipart-with-body.txt +0 -16
  98. data/spec/riak/bucket_spec.rb +0 -230
  99. data/spec/riak/client_spec.rb +0 -174
  100. data/spec/riak/curb_backend_spec.rb +0 -50
  101. data/spec/riak/escape_spec.rb +0 -17
  102. data/spec/riak/http_backend_spec.rb +0 -131
  103. data/spec/riak/link_spec.rb +0 -82
  104. data/spec/riak/map_reduce_spec.rb +0 -352
  105. data/spec/riak/multipart_spec.rb +0 -36
  106. data/spec/riak/object_spec.rb +0 -532
  107. data/spec/riak/walk_spec_spec.rb +0 -208
  108. data/spec/spec.opts +0 -1
  109. data/spec/support/http_backend_implementation_examples.rb +0 -215
  110. 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 'active_support/i18n'
15
- I18n.load_path << File.expand_path("../locale/en.yml", __FILE__)
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
@@ -22,6 +22,10 @@ module Ripple
22
22
  included do
23
23
  attribute_method_suffix ""
24
24
  end
25
+
26
+ def [](attr_name)
27
+ attribute(attr_name)
28
+ end
25
29
 
26
30
  private
27
31
  def attribute(attr_name)
@@ -22,6 +22,10 @@ module Ripple
22
22
  included do
23
23
  attribute_method_suffix "="
24
24
  end
25
+
26
+ def []=(attr_name, value)
27
+ __send__(:attribute=, attr_name, value)
28
+ end
25
29
 
26
30
  private
27
31
  def attribute=(attr_name, value)
@@ -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
- metaclass.send(:define_method, :bucket_name){ value }
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