ocean-dynamo 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2db27622c231e1acb60ff447a2c09e03b5296f8b
4
- data.tar.gz: d52b739be71641641dcc3692beec600b140de494
3
+ metadata.gz: 062bcb5f319f4a5af8ce04446494b1ddbccfdee4
4
+ data.tar.gz: ef17a6d96f6b9185bbf87a9d46a08676b29e3b78
5
5
  SHA512:
6
- metadata.gz: 1ee704329bb3acc6ab272e262450af7100a276d2dc71807ede59defbd39a7407c282b327b2be252096df55d2b2638b6d6e5c14cfe5fdc70067dfe97f461abc82
7
- data.tar.gz: 0f12b591db93660a40edc51e47d56e35d406265e1bf1ada58dc62588b742de29ca7b2ab890e18755637af828685f2fd9bbb4d768fb606207a1bea10f573c9bbc
6
+ metadata.gz: 51c788173b2dfc7adae92e40859d0ef30d0884e70355b5b936a07cc8360aee1bf2eab30993b280534aee6c691427246930ba5ddbbb171018ec5f02b6c36d53d7
7
+ data.tar.gz: 0c2028820ab01793de0a8d3b0712396e2aaa3944d9f9d2c350d6c1400acb48a34d815c61c29c11cc55d91a12133967ee45213d3be33663b51ed4f1f5c8c72c29
data/lib/ocean-dynamo.rb CHANGED
@@ -17,6 +17,7 @@ require "ocean-dynamo/associations/associations"
17
17
  require "ocean-dynamo/associations/association"
18
18
  require "ocean-dynamo/associations/collection_association"
19
19
  require "ocean-dynamo/associations/relation"
20
+ require "ocean-dynamo/associations/collection_proxy"
20
21
  require "ocean-dynamo/associations/belongs_to"
21
22
  require "ocean-dynamo/associations/has_many"
22
23
 
@@ -304,7 +304,7 @@ module ActiveRecord #:nodoc: all
304
304
  end
305
305
  end
306
306
 
307
- # Returns true if the collections is not empty.
307
+ # Returns true if the collection is not empty.
308
308
  # Equivalent to +!collection.empty?+.
309
309
  def any?
310
310
  if block_given?
@@ -25,7 +25,7 @@ module ActiveRecord #:nodoc: all
25
25
  # The <tt>@target</tt> object is not \loaded until needed.
26
26
  #
27
27
  class CollectionProxy < Relation #:nodoc: all
28
- #delegate(*(ActiveRecord::Calculations.public_instance_methods - [:count]), to: :scope)
28
+ delegate(*(ActiveRecord::Calculations.public_instance_methods - [:count]), to: :scope)
29
29
 
30
30
  def initialize(klass, association)
31
31
  @association = association
@@ -101,8 +101,8 @@ module OceanDynamo
101
101
 
102
102
  #
103
103
  # Returns the class of the target. belongs_to polymorphic used to override this
104
- # to look at the polymorphic_type field on the owner. However, belongs_to is no
105
- # longer implemented in AR using an Assocation, so we keep this only for structural
104
+ # to look at the polymorphic_type field on the owner. However, as belongs_to is no
105
+ # longer implemented in AR using an Assocation, we keep this only for structural
106
106
  # compatibility.
107
107
  #
108
108
  def klass
@@ -115,7 +115,7 @@ module OceanDynamo
115
115
 
116
116
 
117
117
  #
118
- # Returns true if the class has a belongs_to association.
118
+ # Returns +true+ if the class has a +belongs_to+ association.
119
119
  #
120
120
  def has_belongs_to?
121
121
  fields[table_hash_key]['association'] == :belongs_to
@@ -124,7 +124,7 @@ module OceanDynamo
124
124
 
125
125
 
126
126
  #
127
- # Returns the class of the belongs_to association, or false if none.
127
+ # Returns the class of the +belongs_to+ association, or +false+ if none.
128
128
  #
129
129
  def belongs_to_class
130
130
  has_belongs_to? && fields[table_hash_key]['target_class']
@@ -135,17 +135,7 @@ module OceanDynamo
135
135
  protected
136
136
 
137
137
  #
138
- # belongs_to can be specified only once in each model, since we use the range key to
139
- # store its UUID and the hash key to store the UUID of the parent, as in
140
- # ["parent_uuid", "child_uuid"]. This allows the parent to find all its children
141
- # extremely efficiently by using only the primary index. It also allows the child
142
- # to find its parent using only its own hash key. Presto: scalability without any
143
- # secondary indices in the has_many/belongs_to association.
144
- #
145
- # Caveat: the parent must have a simple primary key, not a composite one. It *is*
146
- # possible to use a composite key, but then the children must use scans to find
147
- # their parents. We could conditionalise this, of course, so that the lookup
148
- # strategy is transparent to the user.
138
+ # Make sure the class doesn't already have a +belongs_to+ relation.
149
139
  #
150
140
  def assert_only_one_belongs_to! # :nodoc:
151
141
  if has_belongs_to?
@@ -166,7 +156,7 @@ module OceanDynamo
166
156
 
167
157
 
168
158
  #
169
- # Make sure the hash key isn't called :id.
159
+ # Make sure the hash key isn't named <tt>:id</tt>.
170
160
  #
171
161
  def assert_hash_key_is_not_id! # :nodoc:
172
162
  raise HashKeyMayNotBeNamedId,
@@ -5,10 +5,11 @@ module OceanDynamo
5
5
  # ease the implementation of association proxies that represent
6
6
  # collections. See the class hierarchy in AssociationProxy.
7
7
  #
8
- # CollectionAssociation:
9
- # HasAndBelongsToManyAssociation => has_and_belongs_to_many
10
- # HasManyAssociation => has_many
11
- # HasManyThroughAssociation + ThroughAssociation => has_many :through
8
+ # Association
9
+ # CollectionAssociation:
10
+ # HasAndBelongsToManyAssociation => has_and_belongs_to_many
11
+ # HasManyAssociation => has_many
12
+ # HasManyThroughAssociation + ThroughAssociation => has_many :through
12
13
  #
13
14
  # CollectionAssociation class provides common methods to the collections
14
15
  # defined by +has_and_belongs_to_many+, +has_many+ or +has_many+ with
@@ -0,0 +1,211 @@
1
+ module OceanDynamo
2
+ module Associations
3
+ #
4
+ # Collection proxies in OceanDynamo are middlemen between the object that
5
+ # holds the association, known as the <tt>@owner</tt>, and the actual associated
6
+ # object, known as the <tt>@target</tt>. The kind of association any proxy is
7
+ # about is available in <tt>@reflection</tt>. That's an instance of the class
8
+ # OceanDynamo::Reflection::AssociationReflection.
9
+ #
10
+ # For example, given
11
+ #
12
+ # class Blog < OceanDynamo::Table
13
+ # has_many :posts
14
+ # end
15
+ #
16
+ # blog = Blog.first
17
+ #
18
+ # the collection proxy in <tt>blog.posts</tt> has the object in +blog+ as
19
+ # <tt>@owner</tt>, the collection of its posts as <tt>@target</tt>, and
20
+ # the <tt>@reflection</tt> object represents a <tt>:has_many</tt> macro.
21
+ #
22
+ # This class delegates unknown methods to <tt>@target</tt> NOT via
23
+ # <tt>method_missing</tt> (as the ActiveRecord documentation falsely states),
24
+ # but through explicit proxy methods for each separate operation.
25
+ #
26
+ # The <tt>@target</tt> object is not \loaded until needed. As it turns out,
27
+ # the key to this lazy loading scheme is <tt>to_ary</tt>.
28
+ #
29
+ #
30
+ # Inheritance chain:
31
+ #
32
+ # Relation (@klass, @loaded)
33
+ # CollectionProxy (@association)
34
+ #
35
+
36
+
37
+
38
+ class CollectionProxy < Relation
39
+
40
+
41
+ def initialize(klass, association)
42
+ @association = association
43
+ super klass
44
+ end
45
+
46
+
47
+ def proxy_association
48
+ @association
49
+ end
50
+
51
+
52
+ def target
53
+ @association.target
54
+ end
55
+
56
+
57
+ def load_target
58
+ @association.load_target
59
+ end
60
+
61
+
62
+ def loaded?
63
+ @association.loaded?
64
+ end
65
+
66
+
67
+ def select(select = nil, &block)
68
+ @association.select(select, &block)
69
+ end
70
+
71
+
72
+ def find(*args, &block)
73
+ @association.find(*args, &block)
74
+ end
75
+
76
+
77
+ def first(*args)
78
+ @association.first(*args)
79
+ end
80
+
81
+
82
+ def last(*args)
83
+ @association.last(*args)
84
+ end
85
+
86
+
87
+ def build(attributes = {}, &block)
88
+ @association.build(attributes, &block)
89
+ end
90
+ alias_method :new, :build
91
+
92
+
93
+ def create(attributes = {}, &block)
94
+ @association.create(attributes, &block)
95
+ end
96
+
97
+
98
+ def create!(attributes = {}, &block)
99
+ @association.create!(attributes, &block)
100
+ end
101
+
102
+
103
+ def concat(*records)
104
+ @association.concat(*records)
105
+ end
106
+
107
+
108
+ def replace(other_array)
109
+ @association.replace(other_array)
110
+ end
111
+
112
+
113
+ def delete_all
114
+ @association.delete_all
115
+ end
116
+
117
+
118
+ def clear
119
+ delete_all
120
+ self
121
+ end
122
+
123
+
124
+ def destroy_all
125
+ @association.destroy_all
126
+ end
127
+
128
+
129
+ def delete(*records)
130
+ @association.delete(*records)
131
+ end
132
+
133
+
134
+ def destroy(*records)
135
+ @association.destroy(*records)
136
+ end
137
+
138
+
139
+ def distinct
140
+ @association.distinct
141
+ end
142
+ alias uniq distinct
143
+
144
+
145
+ def count(column_name = nil, options = {})
146
+ @association.count(column_name, options)
147
+ end
148
+
149
+
150
+ def size
151
+ @association.size
152
+ end
153
+
154
+
155
+ def length
156
+ @association.length
157
+ end
158
+
159
+
160
+ def empty?
161
+ @association.empty?
162
+ end
163
+
164
+
165
+ def any?(&block)
166
+ @association.any?(&block)
167
+ end
168
+
169
+
170
+ def many?(&block)
171
+ @association.many?(&block)
172
+ end
173
+
174
+
175
+ def include?(record)
176
+ @association.include?(record)
177
+ end
178
+
179
+
180
+ def ==(other)
181
+ load_target == other
182
+ end
183
+
184
+
185
+ def to_ary
186
+ load_target.dup
187
+ end
188
+ alias_method :to_a, :to_ary
189
+
190
+
191
+ def <<(*records)
192
+ proxy_association.concat(records) && self
193
+ end
194
+ alias_method :push, :<<
195
+ alias_method :append, :<<
196
+
197
+
198
+ def prepend(*args)
199
+ raise NoMethodError, "prepend on association is not defined. Please use << or append"
200
+ end
201
+
202
+
203
+ def reload
204
+ proxy_association.reload
205
+ self
206
+ end
207
+
208
+
209
+ end
210
+ end
211
+ end
@@ -1,18 +1,29 @@
1
1
  module OceanDynamo
2
2
 
3
+
4
+ #
5
+ # Relation is a stripped-down version of the corresponding ActiveRecord
6
+ # class. OceanDynamo doesn't implement scopes or counter caches, which
7
+ # simplifies the code considerably.
8
+ #
9
+ # Inheritance chain:
10
+ #
11
+ # Relation (@klass, @loaded)
12
+ # CollectionProxy (@association)
13
+ #
14
+ #
15
+
3
16
  class Relation
4
17
 
5
18
  attr_reader :klass
6
- attr_reader :values
7
19
  attr_reader :loaded
8
20
 
9
21
  alias :model :klass
10
22
  alias :loaded? :loaded
11
23
 
12
24
 
13
- def initialize(klass, **values)
25
+ def initialize(klass)
14
26
  @klass = klass
15
- @values = values
16
27
  @loaded = false
17
28
  end
18
29
 
@@ -27,11 +27,6 @@ module OceanDynamo
27
27
  alias find_by_id find_by_key
28
28
 
29
29
 
30
- # def find_by_id(*args)
31
- # find_by_key(*args)
32
- # end
33
-
34
-
35
30
  #
36
31
  # The number of records in the table.
37
32
  #
@@ -57,7 +57,6 @@ module OceanDynamo
57
57
 
58
58
 
59
59
  def setup_dynamo
60
- #self.dynamo_client = AWS::DynamoDB::Client.new(:api_version => '2012-08-10')
61
60
  self.dynamo_client ||= AWS::DynamoDB.new
62
61
  self.dynamo_table = dynamo_client.tables[table_full_name]
63
62
  self.dynamo_items = dynamo_table.items
@@ -1,3 +1,3 @@
1
1
  module OceanDynamo
2
- VERSION = "0.5.3"
2
+ VERSION = "0.5.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ocean-dynamo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Bengtson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-07 00:00:00.000000000 Z
11
+ date: 2013-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -148,11 +148,10 @@ description: "== OceanDynamo\n\nOceanDynamo is a massively scalable Amazon Dynam
148
148
  to. The design goal \nis always to implement as much of the ActiveRecord interface
149
149
  as possible, without \ncompromising scalability. This makes the task of switching
150
150
  from SQL to no-SQL much easier.\n\nThanks to its structural similarity to ActiveRecord,
151
- OceanDynamo works with FactoryGirl.\nTo facilitate testing, future versions will
152
- keep track of and delete instances after tests.\n\nOceanDynamo uses primary indices
153
- to retrieve related table items, \nwhich means it will scale without limits.\n\nSee
154
- also Ocean, a Rails framework for creating highly scalable SOAs in the cloud, in
155
- which\nocean-dynamo is used as a central component: http://wiki.oceanframework.net"
151
+ OceanDynamo works with FactoryGirl.\n\nOceanDynamo uses primary indices to retrieve
152
+ related table items, \nmeaning it scales without limits.\n\nSee also Ocean, a Rails
153
+ framework for creating highly scalable SOAs in the cloud, in which\nocean-dynamo
154
+ is used as a central component: http://wiki.oceanframework.net"
156
155
  email:
157
156
  - peter@peterbengtson.com
158
157
  executables: []
@@ -171,6 +170,7 @@ files:
171
170
  - lib/ocean-dynamo/associations/associations.rb
172
171
  - lib/ocean-dynamo/associations/belongs_to.rb
173
172
  - lib/ocean-dynamo/associations/collection_association.rb
173
+ - lib/ocean-dynamo/associations/collection_proxy.rb
174
174
  - lib/ocean-dynamo/associations/has_many.rb
175
175
  - lib/ocean-dynamo/associations/relation.rb
176
176
  - lib/ocean-dynamo/attributes.rb
@@ -197,9 +197,9 @@ require_paths:
197
197
  - lib
198
198
  required_ruby_version: !ruby/object:Gem::Requirement
199
199
  requirements:
200
- - - '>='
200
+ - - ~>
201
201
  - !ruby/object:Gem::Version
202
- version: 2.0.0
202
+ version: '2'
203
203
  required_rubygems_version: !ruby/object:Gem::Requirement
204
204
  requirements:
205
205
  - - '>='