ripple 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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