synamoid 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,69 +0,0 @@
1
- # encoding: utf-8
2
- module Dynamoid #:nodoc:
3
-
4
- module Associations
5
- module SingleAssociation
6
- include Association
7
-
8
- delegate :class, :to => :target
9
-
10
- def setter(object)
11
- delete
12
- source.update_attribute(source_attribute, Set[object.hash_key])
13
- self.send(:associate_target, object) if target_association
14
- object
15
- end
16
-
17
- def delete
18
- source.update_attribute(source_attribute, nil)
19
- self.send(:disassociate_target, target) if target && target_association
20
- target
21
- end
22
-
23
- def create!(attributes = {})
24
- setter(target_class.create!(attributes))
25
- end
26
-
27
- def create(attributes = {})
28
- setter(target_class.create(attributes))
29
- end
30
-
31
-
32
- # Is this object equal to the association's target?
33
- #
34
- # @return [Boolean] true/false
35
- #
36
- # @since 0.2.0
37
- def ==(other)
38
- target == other
39
- end
40
-
41
- # Delegate methods we don't find directly to the target.
42
- #
43
- # @since 0.2.0
44
- def method_missing(method, *args)
45
- if target.respond_to?(method)
46
- target.send(method, *args)
47
- else
48
- super
49
- end
50
- end
51
-
52
- def nil?
53
- target.nil?
54
- end
55
-
56
- private
57
-
58
- # Find the target of the has_one association.
59
- #
60
- # @return [Dynamoid::Document] the found target (or nil if nothing)
61
- #
62
- # @since 0.2.0
63
- def find_target
64
- return if source_ids.empty?
65
- target_class.find(source_ids.first)
66
- end
67
- end
68
- end
69
- end
@@ -1,37 +0,0 @@
1
- # encoding: utf-8
2
- module Dynamoid
3
-
4
- # All modules that a Document is composed of are defined in this
5
- # module, to keep the document class from getting too cluttered.
6
- module Components
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
- extend ActiveModel::Translation
11
- extend ActiveModel::Callbacks
12
-
13
- define_model_callbacks :create, :save, :destroy, :initialize, :update
14
-
15
- before_create :set_created_at
16
- before_save :set_updated_at
17
- after_initialize :set_type
18
- end
19
-
20
- include ActiveModel::AttributeMethods
21
- include ActiveModel::Conversion
22
- include ActiveModel::MassAssignmentSecurity if defined?(ActiveModel::MassAssignmentSecurity)
23
- include ActiveModel::Naming
24
- include ActiveModel::Observing if defined?(ActiveModel::Observing)
25
- include ActiveModel::Serializers::JSON
26
- include ActiveModel::Serializers::Xml
27
- include Dynamoid::Fields
28
- include Dynamoid::Indexes
29
- include Dynamoid::Persistence
30
- include Dynamoid::Finders
31
- include Dynamoid::Associations
32
- include Dynamoid::Criteria
33
- include Dynamoid::Validations
34
- include Dynamoid::IdentityMap
35
- include Dynamoid::Dirty
36
- end
37
- end
@@ -1,58 +0,0 @@
1
- # encoding: utf-8
2
- require "uri"
3
- require "dynamoid/config/options"
4
-
5
- module Dynamoid
6
-
7
- # Contains all the basic configuration information required for Dynamoid: both sensible defaults and required fields.
8
- module Config
9
- extend self
10
- extend Options
11
- include ActiveModel::Observing if defined?(ActiveModel::Observing)
12
-
13
- # All the default options.
14
- option :adapter, :default => 'aws_sdk_v2'
15
- option :namespace, :default => defined?(Rails) ? "dynamoid_#{Rails.application.class.parent_name}_#{Rails.env}" : "dynamoid"
16
- option :logger, :default => defined?(Rails)
17
- option :access_key
18
- option :secret_key
19
- option :read_capacity, :default => 100
20
- option :write_capacity, :default => 20
21
- option :warn_on_scan, :default => true
22
- option :endpoint, :default => nil
23
- option :use_ssl, :default => true
24
- option :port, :default => '443'
25
- option :identity_map, :default => false
26
- option :timestamps, :default => true
27
- option :sync_retry_max_times, :default => 60 # a bit over 2 minutes
28
- option :sync_retry_wait_seconds, :default => 2
29
- option :convert_big_decimal, :default => false
30
-
31
- # The default logger for Dynamoid: either the Rails logger or just stdout.
32
- #
33
- # @since 0.2.0
34
- def default_logger
35
- defined?(Rails) && Rails.respond_to?(:logger) ? Rails.logger : ::Logger.new($stdout)
36
- end
37
-
38
- # Returns the assigned logger instance.
39
- #
40
- # @since 0.2.0
41
- def logger
42
- @logger ||= default_logger
43
- end
44
-
45
- # If you want to, set the logger manually to any output you'd like. Or pass false or nil to disable logging entirely.
46
- #
47
- # @since 0.2.0
48
- def logger=(logger)
49
- case logger
50
- when false, nil then @logger = nil
51
- when true then @logger = default_logger
52
- else
53
- @logger = logger if logger.respond_to?(:info)
54
- end
55
- end
56
-
57
- end
58
- end
@@ -1,78 +0,0 @@
1
- # Shamelessly stolen from Mongoid!
2
- module Dynamoid #:nodoc
3
- module Config
4
-
5
- # Encapsulates logic for setting options.
6
- module Options
7
-
8
- # Get the defaults or initialize a new empty hash.
9
- #
10
- # @example Get the defaults.
11
- # options.defaults
12
- #
13
- # @return [ Hash ] The default options.
14
- #
15
- # @since 0.2.0
16
- def defaults
17
- @defaults ||= {}
18
- end
19
-
20
- # Define a configuration option with a default.
21
- #
22
- # @example Define the option.
23
- # Options.option(:persist_in_safe_mode, :default => false)
24
- #
25
- # @param [ Symbol ] name The name of the configuration option.
26
- # @param [ Hash ] options Extras for the option.
27
- #
28
- # @option options [ Object ] :default The default value.
29
- #
30
- # @since 0.2.0
31
- def option(name, options = {})
32
- defaults[name] = settings[name] = options[:default]
33
-
34
- class_eval <<-RUBY
35
- def #{name}
36
- settings[#{name.inspect}]
37
- end
38
-
39
- def #{name}=(value)
40
- settings[#{name.inspect}] = value
41
- end
42
-
43
- def #{name}?
44
- #{name}
45
- end
46
-
47
- def reset_#{name}
48
- settings[#{name.inspect}] = defaults[#{name.inspect}]
49
- end
50
- RUBY
51
- end
52
-
53
- # Reset the configuration options to the defaults.
54
- #
55
- # @example Reset the configuration options.
56
- # config.reset
57
- #
58
- # @return [ Hash ] The defaults.
59
- #
60
- # @since 0.2.0
61
- def reset
62
- settings.replace(defaults)
63
- end
64
-
65
- # Get the settings or initialize a new empty hash.
66
- #
67
- # @example Get the settings.
68
- # options.settings
69
- #
70
- # @return [ Hash ] The setting options.
71
- #
72
- # @since 0.2.0
73
- def settings
74
- @settings ||= {}
75
- end
76
- end
77
- end
78
- end
@@ -1,29 +0,0 @@
1
- # encoding: utf-8
2
- require 'dynamoid/criteria/chain'
3
-
4
- module Dynamoid
5
-
6
- # Allows classes to be queried by where, all, first, and each and return criteria chains.
7
- module Criteria
8
- extend ActiveSupport::Concern
9
-
10
- module ClassMethods
11
-
12
- [:where, :all, :first, :each, :eval_limit, :start, :scan_index_forward].each do |meth|
13
- # Return a criteria chain in response to a method that will begin or end a chain. For more information,
14
- # see Dynamoid::Criteria::Chain.
15
- #
16
- # @since 0.2.0
17
- define_method(meth) do |*args|
18
- chain = Dynamoid::Criteria::Chain.new(self)
19
- if args
20
- chain.send(meth, *args)
21
- else
22
- chain.send(meth)
23
- end
24
- end
25
- end
26
- end
27
- end
28
-
29
- end
@@ -1,214 +0,0 @@
1
- # encoding: utf-8
2
- module Dynamoid #:nodoc:
3
- module Criteria
4
-
5
- # The criteria chain is equivalent to an ActiveRecord relation (and realistically I should change the name from
6
- # chain to relation). It is a chainable object that builds up a query and eventually executes it by a Query or Scan.
7
- class Chain
8
- attr_accessor :query, :source, :values, :consistent_read
9
- include Enumerable
10
-
11
- # Create a new criteria chain.
12
- #
13
- # @param [Class] source the class upon which the ultimate query will be performed.
14
- def initialize(source)
15
- @query = {}
16
- @source = source
17
- @consistent_read = false
18
- @scan_index_forward = true
19
- end
20
-
21
- # The workhorse method of the criteria chain. Each key in the passed in hash will become another criteria that the
22
- # ultimate query must match. A key can either be a symbol or a string, and should be an attribute name or
23
- # an attribute name with a range operator.
24
- #
25
- # @example A simple criteria
26
- # where(:name => 'Josh')
27
- #
28
- # @example A more complicated criteria
29
- # where(:name => 'Josh', 'created_at.gt' => DateTime.now - 1.day)
30
- #
31
- # @since 0.2.0
32
- def where(args)
33
- args.each {|k, v| query[k.to_sym] = v}
34
- self
35
- end
36
-
37
- def consistent
38
- @consistent_read = true
39
- self
40
- end
41
-
42
- # Returns all the records matching the criteria.
43
- #
44
- # @since 0.2.0
45
- def all
46
- records
47
- end
48
-
49
- # Destroys all the records matching the criteria.
50
- #
51
- def destroy_all
52
- ids = []
53
-
54
- if key_present?
55
- ranges = []
56
- Dynamoid.adapter.query(source.table_name, range_query).collect do |hash|
57
- ids << hash[source.hash_key.to_sym]
58
- ranges << hash[source.range_key.to_sym]
59
- end
60
-
61
- Dynamoid.adapter.delete(source.table_name, ids,{:range_key => ranges})
62
- else
63
- Dynamoid.adapter.scan(source.table_name, query, scan_opts).collect do |hash|
64
- ids << hash[source.hash_key.to_sym]
65
- end
66
-
67
- Dynamoid.adapter.delete(source.table_name, ids)
68
- end
69
- end
70
-
71
- def eval_limit(limit)
72
- @eval_limit = limit
73
- self
74
- end
75
-
76
- def batch(batch_size)
77
- @batch_size = batch_size
78
- self
79
- end
80
-
81
- def start(start)
82
- @start = start
83
- self
84
- end
85
-
86
- def scan_index_forward(scan_index_forward)
87
- @scan_index_forward = scan_index_forward
88
- self
89
- end
90
-
91
- # Allows you to use the results of a search as an enumerable over the results found.
92
- #
93
- # @since 0.2.0
94
- def each(&block)
95
- records.each(&block)
96
- end
97
-
98
- def consistent_opts
99
- { :consistent_read => consistent_read }
100
- end
101
-
102
- private
103
-
104
- # The actual records referenced by the association.
105
- #
106
- # @return [Enumerator] an iterator of the found records.
107
- #
108
- # @since 0.2.0
109
- def records
110
- results = if key_present?
111
- records_via_query
112
- else
113
- records_via_scan
114
- end
115
- @batch_size ? results : Array(results)
116
- end
117
-
118
- def records_via_query
119
- Enumerator.new do |yielder|
120
- Dynamoid.adapter.query(source.table_name, range_query).each do |hash|
121
- yielder.yield source.from_database(hash)
122
- end
123
- end
124
- end
125
-
126
- # If the query does not match an index, we'll manually scan the associated table to find results.
127
- #
128
- # @return [Enumerator] an iterator of the found records.
129
- #
130
- # @since 0.2.0
131
- def records_via_scan
132
- if Dynamoid::Config.warn_on_scan
133
- Dynamoid.logger.warn 'Queries without an index are forced to use scan and are generally much slower than indexed queries!'
134
- Dynamoid.logger.warn "You can index this query by adding this to #{source.to_s.downcase}.rb: index [#{source.attributes.sort.collect{|attr| ":#{attr}"}.join(', ')}]"
135
- end
136
-
137
- if @consistent_read
138
- raise Dynamoid::Errors::InvalidQuery, 'Consistent read is not supported by SCAN operation'
139
- end
140
-
141
- Enumerator.new do |yielder|
142
- Dynamoid.adapter.scan(source.table_name, query, scan_opts).each do |hash|
143
- yielder.yield source.from_database(hash)
144
- end
145
- end
146
- end
147
-
148
- def range_hash(key)
149
- val = query[key]
150
-
151
- return { :range_value => query[key] } if query[key].is_a?(Range)
152
-
153
- case key.to_s.split('.').last
154
- when 'gt'
155
- { :range_greater_than => val }
156
- when 'lt'
157
- { :range_less_than => val }
158
- when 'gte'
159
- { :range_gte => val }
160
- when 'lte'
161
- { :range_lte => val }
162
- when 'between'
163
- { :range_between => val }
164
- when 'begins_with'
165
- { :range_begins_with => val }
166
- end
167
- end
168
-
169
- def range_query
170
- opts = { :hash_value => query[source.hash_key] }
171
- query.keys.select { |k| k.to_s.include?('.') }.each do |key|
172
- opts.merge!(range_hash(key))
173
- end
174
- opts.merge(query_opts).merge(consistent_opts)
175
- end
176
-
177
- def query_keys
178
- query.keys.collect{|k| k.to_s.split('.').first}
179
- end
180
-
181
- # [hash_key] or [hash_key, range_key] is specified in query keys.
182
- def key_present?
183
- query_keys == [source.hash_key.to_s] || (query_keys.to_set == [source.hash_key.to_s, source.range_key.to_s].to_set)
184
- end
185
-
186
- def start_key
187
- key = { :hash_key_element => @start.hash_key }
188
- if range_key = @start.class.range_key
189
- key.merge!({:range_key_element => @start.send(range_key) })
190
- end
191
- key
192
- end
193
-
194
- def query_opts
195
- opts = {}
196
- opts[:select] = 'ALL_ATTRIBUTES'
197
- opts[:limit] = @eval_limit if @eval_limit
198
- opts[:next_token] = start_key if @start
199
- opts[:scan_index_forward] = @scan_index_forward
200
- opts
201
- end
202
-
203
- def scan_opts
204
- opts = {}
205
- opts[:limit] = @eval_limit if @eval_limit
206
- opts[:next_token] = start_key if @start
207
- opts[:batch_size] = @batch_size if @batch_size
208
- opts
209
- end
210
- end
211
-
212
- end
213
-
214
- end