dynamoid 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Dynamoid.gemspec +5 -3
- data/README.markdown +2 -2
- data/VERSION +1 -1
- data/doc/Dynamoid.html +26 -14
- data/doc/Dynamoid/Adapter.html +33 -35
- data/doc/Dynamoid/Adapter/AwsSdk.html +177 -153
- data/doc/Dynamoid/Adapter/Local.html +144 -57
- data/doc/Dynamoid/Associations.html +3 -3
- data/doc/Dynamoid/Associations/Association.html +104 -1016
- data/doc/Dynamoid/Associations/BelongsTo.html +11 -192
- data/doc/Dynamoid/Associations/ClassMethods.html +17 -17
- data/doc/Dynamoid/Associations/HasAndBelongsToMany.html +15 -190
- data/doc/Dynamoid/Associations/HasMany.html +15 -190
- data/doc/Dynamoid/Associations/HasOne.html +11 -192
- data/doc/Dynamoid/Associations/ManyAssociation.html +1640 -0
- data/doc/Dynamoid/Associations/SingleAssociation.html +598 -0
- data/doc/Dynamoid/Components.html +4 -2
- data/doc/Dynamoid/Config.html +10 -10
- data/doc/Dynamoid/Config/Options.html +1 -1
- data/doc/Dynamoid/Criteria.html +1 -1
- data/doc/Dynamoid/Criteria/Chain.html +326 -22
- data/doc/Dynamoid/Criteria/ClassMethods.html +1 -1
- data/doc/Dynamoid/Document.html +181 -27
- data/doc/Dynamoid/Document/ClassMethods.html +392 -36
- data/doc/Dynamoid/Errors.html +1 -1
- data/doc/Dynamoid/Errors/DocumentNotValid.html +1 -1
- data/doc/Dynamoid/Errors/Error.html +1 -1
- data/doc/Dynamoid/Errors/InvalidField.html +1 -1
- data/doc/Dynamoid/Errors/MissingRangeKey.html +1 -1
- data/doc/Dynamoid/Fields.html +44 -24
- data/doc/Dynamoid/Fields/ClassMethods.html +60 -15
- data/doc/Dynamoid/Finders.html +1 -1
- data/doc/Dynamoid/Finders/ClassMethods.html +45 -31
- data/doc/Dynamoid/Indexes.html +7 -7
- data/doc/Dynamoid/Indexes/ClassMethods.html +6 -4
- data/doc/Dynamoid/Indexes/Index.html +47 -32
- data/doc/Dynamoid/Persistence.html +47 -49
- data/doc/Dynamoid/Persistence/ClassMethods.html +149 -47
- data/doc/Dynamoid/Validations.html +1 -1
- data/doc/_index.html +35 -13
- data/doc/class_list.html +1 -1
- data/doc/file.LICENSE.html +1 -1
- data/doc/file.README.html +37 -4
- data/doc/index.html +37 -4
- data/doc/method_list.html +320 -136
- data/doc/top-level-namespace.html +1 -1
- data/lib/dynamoid/adapter.rb +28 -30
- data/lib/dynamoid/adapter/aws_sdk.rb +23 -22
- data/lib/dynamoid/persistence.rb +33 -27
- metadata +6 -4
data/lib/dynamoid/adapter.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Dynamoid
|
3
3
|
|
4
|
-
# Adapter provides a generic, write-through class that abstracts variations in the underlying connections to provide a uniform response
|
4
|
+
# Adapter provides a generic, write-through class that abstracts variations in the underlying connections to provide a uniform response
|
5
5
|
# to Dynamoid.
|
6
6
|
module Adapter
|
7
7
|
extend self
|
8
8
|
attr_accessor :tables
|
9
|
-
|
9
|
+
|
10
10
|
# The actual adapter currently in use: presently, either AwsSdk or Local.
|
11
11
|
#
|
12
12
|
# @since 0.2.0
|
@@ -14,7 +14,7 @@ module Dynamoid
|
|
14
14
|
reconnect! unless @adapter
|
15
15
|
@adapter
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
# Establishes a connection to the underyling adapter and caches all its tables for speedier future lookups. Issued when the adapter is first called.
|
19
19
|
#
|
20
20
|
# @since 0.2.0
|
@@ -24,7 +24,7 @@ module Dynamoid
|
|
24
24
|
@adapter.connect! if @adapter.respond_to?(:connect!)
|
25
25
|
self.tables = benchmark('Cache Tables') {list_tables}
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
# Shows how long it takes a method to run on the adapter. Useful for generating logged output.
|
29
29
|
#
|
30
30
|
# @param [Symbol] method the name of the method to appear in the log
|
@@ -40,7 +40,7 @@ module Dynamoid
|
|
40
40
|
Dynamoid.logger.info "(#{((Time.now - start) * 1000.0).round(2)} ms) #{method.to_s.split('_').collect(&:upcase).join(' ')}#{ " - #{args.inspect}" unless args.nil? || args.empty? }"
|
41
41
|
return result
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
# Write an object to the adapter. Partition it to a randomly selected key first if necessary.
|
45
45
|
#
|
46
46
|
# @param [String] table the name of the table to write the object to
|
@@ -54,12 +54,12 @@ module Dynamoid
|
|
54
54
|
object[:id] = "#{object[:id]}.#{Random.rand(Dynamoid::Config.partition_size)}"
|
55
55
|
object[:updated_at] = Time.now.to_f
|
56
56
|
end
|
57
|
-
|
57
|
+
put_item(table, object)
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
# Read one or many keys from the selected table. This method intelligently calls batch_get or get on the underlying adapter depending on
|
61
61
|
# whether ids is a range or a single key: additionally, if partitioning is enabled, it batch_gets all keys in the partition space
|
62
|
-
# automatically. Finally, if a range key is present, it will also interpolate that into the ids so that the batch get will acquire the
|
62
|
+
# automatically. Finally, if a range key is present, it will also interpolate that into the ids so that the batch get will acquire the
|
63
63
|
# correct record.
|
64
64
|
#
|
65
65
|
# @param [String] table the name of the table to write the object to
|
@@ -72,22 +72,22 @@ module Dynamoid
|
|
72
72
|
if ids.respond_to?(:each)
|
73
73
|
ids = ids.collect{|id| range_key ? [id, range_key] : id}
|
74
74
|
if Dynamoid::Config.partitioning?
|
75
|
-
results =
|
75
|
+
results = batch_get_item(table => id_with_partitions(ids))
|
76
76
|
{table => result_for_partition(results[table])}
|
77
77
|
else
|
78
|
-
|
78
|
+
batch_get_item(table => ids)
|
79
79
|
end
|
80
80
|
else
|
81
81
|
if Dynamoid::Config.partitioning?
|
82
82
|
ids = range_key ? [[ids, range_key]] : ids
|
83
|
-
results =
|
83
|
+
results = batch_get_item(table => id_with_partitions(ids))
|
84
84
|
result_for_partition(results[table]).first
|
85
85
|
else
|
86
|
-
|
86
|
+
get_item(table, ids, options)
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
# Delete an item from a table. If partitioning is turned on, deletes all partitioned keys as well.
|
92
92
|
#
|
93
93
|
# @param [String] table the name of the table to write the object to
|
@@ -97,29 +97,27 @@ module Dynamoid
|
|
97
97
|
# @since 0.2.0
|
98
98
|
def delete(table, id, options = {})
|
99
99
|
if Dynamoid::Config.partitioning?
|
100
|
-
|
101
|
-
id_with_partitions(id).each {|i| delete_item(table, i, options)}
|
102
|
-
end
|
100
|
+
id_with_partitions(id).each {|i| delete_item(table, i, options)}
|
103
101
|
else
|
104
|
-
|
102
|
+
delete_item(table, id, options)
|
105
103
|
end
|
106
104
|
end
|
107
|
-
|
105
|
+
|
108
106
|
# Scans a table. Generally quite slow; try to avoid using scan if at all possible.
|
109
107
|
#
|
110
108
|
# @param [String] table the name of the table to write the object to
|
111
109
|
# @param [Hash] scan_hash a hash of attributes: matching records will be returned by the scan
|
112
110
|
#
|
113
|
-
# @since 0.2.0
|
111
|
+
# @since 0.2.0
|
114
112
|
def scan(table, query, opts = {})
|
115
113
|
if Dynamoid::Config.partitioning?
|
116
114
|
results = benchmark('Scan', table, query) {adapter.scan(table, query, opts)}
|
117
115
|
result_for_partition(results)
|
118
116
|
else
|
119
|
-
adapter.scan(table, query, opts)
|
117
|
+
benchmark('Scan', table, query) {adapter.scan(table, query, opts)}
|
120
118
|
end
|
121
119
|
end
|
122
|
-
|
120
|
+
|
123
121
|
[:batch_get_item, :create_table, :delete_item, :delete_table, :get_item, :list_tables, :put_item].each do |m|
|
124
122
|
# Method delegation with benchmark to the underlying adapter. Faster than relying on method_missing.
|
125
123
|
#
|
@@ -128,8 +126,8 @@ module Dynamoid
|
|
128
126
|
benchmark("#{m.to_s}", args) {adapter.send(m, *args)}
|
129
127
|
end
|
130
128
|
end
|
131
|
-
|
132
|
-
# Takes a list of ids and returns them with partitioning added. If an array of arrays is passed, we assume the second key is the range key
|
129
|
+
|
130
|
+
# Takes a list of ids and returns them with partitioning added. If an array of arrays is passed, we assume the second key is the range key
|
133
131
|
# and pass it in unchanged.
|
134
132
|
#
|
135
133
|
# @example Partition id 1
|
@@ -139,15 +137,15 @@ module Dynamoid
|
|
139
137
|
#
|
140
138
|
# @param [Array] ids array of ids to partition
|
141
139
|
#
|
142
|
-
# @since 0.2.0
|
140
|
+
# @since 0.2.0
|
143
141
|
def id_with_partitions(ids)
|
144
142
|
Array(ids).collect {|id| (0...Dynamoid::Config.partition_size).collect{|n| id.is_a?(Array) ? ["#{id.first}.#{n}", id.last] : "#{id}.#{n}"}}.flatten(1)
|
145
143
|
end
|
146
|
-
|
147
|
-
# Takes an array of results that are partitioned, find the most recently updated one, and return only it. Compares each result by
|
144
|
+
|
145
|
+
# Takes an array of results that are partitioned, find the most recently updated one, and return only it. Compares each result by
|
148
146
|
# their id and updated_at attributes; if the updated_at is the greatest, then it must be the correct result.
|
149
147
|
#
|
150
|
-
# @param [Array] returned partitioned results from a query
|
148
|
+
# @param [Array] returned partitioned results from a query
|
151
149
|
#
|
152
150
|
# @since 0.2.0
|
153
151
|
def result_for_partition(results)
|
@@ -162,7 +160,7 @@ module Dynamoid
|
|
162
160
|
end
|
163
161
|
end.values
|
164
162
|
end
|
165
|
-
|
163
|
+
|
166
164
|
# Delegate all methods that aren't defind here to the underlying adapter.
|
167
165
|
#
|
168
166
|
# @since 0.2.0
|
@@ -170,7 +168,7 @@ module Dynamoid
|
|
170
168
|
return benchmark(method, *args) {adapter.send(method, *args)} if @adapter.respond_to?(method)
|
171
169
|
super
|
172
170
|
end
|
173
|
-
|
171
|
+
|
174
172
|
end
|
175
|
-
|
173
|
+
|
176
174
|
end
|
@@ -3,15 +3,15 @@ require 'aws'
|
|
3
3
|
|
4
4
|
module Dynamoid
|
5
5
|
module Adapter
|
6
|
-
|
6
|
+
|
7
7
|
# The AwsSdk adapter provides support for the AWS-SDK for Ruby gem.
|
8
8
|
# More information is available at that Gem's Github page:
|
9
9
|
# https://github.com/amazonwebservices/aws-sdk-for-ruby
|
10
|
-
#
|
10
|
+
#
|
11
11
|
module AwsSdk
|
12
12
|
extend self
|
13
13
|
@@connection = nil
|
14
|
-
|
14
|
+
|
15
15
|
# Establish the connection to DynamoDB.
|
16
16
|
#
|
17
17
|
# @return [AWS::DynamoDB::Connection] the raw DynamoDB connection
|
@@ -20,7 +20,7 @@ module Dynamoid
|
|
20
20
|
def connect!
|
21
21
|
@@connection = AWS::DynamoDB.new(:access_key_id => Dynamoid::Config.access_key, :secret_access_key => Dynamoid::Config.secret_key, :dynamo_db_endpoint => Dynamoid::Config.endpoint)
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# Return the established connection.
|
25
25
|
#
|
26
26
|
# @return [AWS::DynamoDB::Connection] the raw DynamoDB connection
|
@@ -29,16 +29,16 @@ module Dynamoid
|
|
29
29
|
def connection
|
30
30
|
@@connection
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# Get many items at once from DynamoDB. More efficient than getting each item individually.
|
34
|
-
#
|
34
|
+
#
|
35
35
|
# @example Retrieve IDs 1 and 2 from the table testtable
|
36
36
|
# Dynamoid::Adapter::AwsSdk.batch_get_item('table1' => ['1', '2'])
|
37
37
|
#
|
38
38
|
# @param [Hash] options the hash of tables and IDs to retrieve
|
39
39
|
#
|
40
40
|
# @return [Hash] a hash where keys are the table names and the values are the retrieved items
|
41
|
-
#
|
41
|
+
#
|
42
42
|
# @since 0.2.0
|
43
43
|
def batch_get_item(options)
|
44
44
|
hash = Hash.new{|h, k| h[k] = []}
|
@@ -54,15 +54,16 @@ module Dynamoid
|
|
54
54
|
end
|
55
55
|
hash
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
# Create a table on DynamoDB. This usually takes a long time to complete.
|
59
59
|
#
|
60
60
|
# @param [String] table_name the name of the table to create
|
61
61
|
# @param [Symbol] key the table's primary key (defaults to :id)
|
62
62
|
# @param [Hash] options provide a range_key here if you want one for the table
|
63
|
-
#
|
63
|
+
#
|
64
64
|
# @since 0.2.0
|
65
65
|
def create_table(table_name, key = :id, options = {})
|
66
|
+
Dynamite.logger.info "Creating #{table_name} table. This could take a while."
|
66
67
|
options[:hash_key] ||= {key.to_sym => :string}
|
67
68
|
read_capacity = options[:read_capacity] || Dynamoid::Config.read_capacity
|
68
69
|
write_capacity = options[:write_capacity] || Dynamoid::Config.write_capacity
|
@@ -70,7 +71,7 @@ module Dynamoid
|
|
70
71
|
sleep 0.5 while table.status == :creating
|
71
72
|
return table
|
72
73
|
end
|
73
|
-
|
74
|
+
|
74
75
|
# Removes an item from DynamoDB.
|
75
76
|
#
|
76
77
|
# @param [String] table_name the name of the table
|
@@ -89,8 +90,8 @@ module Dynamoid
|
|
89
90
|
result.delete unless result.attributes.to_h.empty?
|
90
91
|
true
|
91
92
|
end
|
92
|
-
|
93
|
-
# Deletes an entire table from DynamoDB. Only 10 tables can be in the deleting state at once,
|
93
|
+
|
94
|
+
# Deletes an entire table from DynamoDB. Only 10 tables can be in the deleting state at once,
|
94
95
|
# so if you have more this method may raise an exception.
|
95
96
|
#
|
96
97
|
# @param [String] table_name the name of the table to destroy
|
@@ -99,9 +100,9 @@ module Dynamoid
|
|
99
100
|
def delete_table(table_name)
|
100
101
|
@@connection.tables[table_name].delete
|
101
102
|
end
|
102
|
-
|
103
|
+
|
103
104
|
# @todo Add a DescribeTable method.
|
104
|
-
|
105
|
+
|
105
106
|
# Fetches an item from DynamoDB.
|
106
107
|
#
|
107
108
|
# @param [String] table_name the name of the table
|
@@ -129,14 +130,14 @@ module Dynamoid
|
|
129
130
|
result.symbolize_keys!
|
130
131
|
end
|
131
132
|
end
|
132
|
-
|
133
|
+
|
133
134
|
# List all tables on DynamoDB.
|
134
135
|
#
|
135
136
|
# @since 0.2.0
|
136
137
|
def list_tables
|
137
138
|
@@connection.tables.collect(&:name)
|
138
139
|
end
|
139
|
-
|
140
|
+
|
140
141
|
# Persists an item on DynamoDB.
|
141
142
|
#
|
142
143
|
# @param [String] table_name the name of the table
|
@@ -147,9 +148,9 @@ module Dynamoid
|
|
147
148
|
table = get_table(table_name)
|
148
149
|
table.items.create(object.delete_if{|k, v| v.nil? || (v.respond_to?(:empty?) && v.empty?)})
|
149
150
|
end
|
150
|
-
|
151
|
-
# Query the DynamoDB table. This employs DynamoDB's indexes so is generally faster than scanning, but is
|
152
|
-
# only really useful for range queries, since it can only find by one hash key at once. Only provide
|
151
|
+
|
152
|
+
# Query the DynamoDB table. This employs DynamoDB's indexes so is generally faster than scanning, but is
|
153
|
+
# only really useful for range queries, since it can only find by one hash key at once. Only provide
|
153
154
|
# one range key to the hash.
|
154
155
|
#
|
155
156
|
# @param [String] table_name the name of the table
|
@@ -176,7 +177,7 @@ module Dynamoid
|
|
176
177
|
get_item(table_name, opts[:hash_value])
|
177
178
|
end
|
178
179
|
end
|
179
|
-
|
180
|
+
|
180
181
|
# Scan the DynamoDB table. This is usually a very slow operation as it naively filters all data on
|
181
182
|
# the DynamoDB servers.
|
182
183
|
#
|
@@ -194,9 +195,9 @@ module Dynamoid
|
|
194
195
|
end
|
195
196
|
results
|
196
197
|
end
|
197
|
-
|
198
|
+
|
198
199
|
# @todo Add an UpdateItem method.
|
199
|
-
|
200
|
+
|
200
201
|
# @todo Add an UpdateTable method.
|
201
202
|
|
202
203
|
def get_table(table_name)
|
data/lib/dynamoid/persistence.rb
CHANGED
@@ -3,23 +3,23 @@ require 'securerandom'
|
|
3
3
|
# encoding: utf-8
|
4
4
|
module Dynamoid
|
5
5
|
|
6
|
-
# Persistence is responsible for dumping objects to and marshalling objects from the datastore. It tries to reserialize
|
6
|
+
# Persistence is responsible for dumping objects to and marshalling objects from the datastore. It tries to reserialize
|
7
7
|
# values to be of the same type as when they were passed in, based on the fields in the class.
|
8
8
|
module Persistence
|
9
9
|
extend ActiveSupport::Concern
|
10
|
-
|
10
|
+
|
11
11
|
attr_accessor :new_record
|
12
12
|
alias :new_record? :new_record
|
13
|
-
|
13
|
+
|
14
14
|
module ClassMethods
|
15
|
-
|
15
|
+
|
16
16
|
# Returns the name of the table the class is for.
|
17
17
|
#
|
18
18
|
# @since 0.2.0
|
19
19
|
def table_name
|
20
20
|
"#{Dynamoid::Config.namespace}_#{options[:name] ? options[:name] : self.name.downcase.pluralize}"
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Creates a table.
|
24
24
|
#
|
25
25
|
# @param [Hash] options options to pass for table creation
|
@@ -31,26 +31,32 @@ module Dynamoid
|
|
31
31
|
#
|
32
32
|
# @since 0.4.0
|
33
33
|
def create_table(options = {})
|
34
|
+
if self.range_key
|
35
|
+
range_key_type = [:integer, :float].include?(attributes[range_key][:type]) ? :number : attributes[range_key][:type]
|
36
|
+
range_key_hash = { range_key => range_key_type}
|
37
|
+
else
|
38
|
+
range_key_hash = nil
|
39
|
+
end
|
34
40
|
options = {
|
35
41
|
:id => self.hash_key,
|
36
42
|
:table_name => self.table_name,
|
37
43
|
:write_capacity => self.write_capacity,
|
38
44
|
:read_capacity => self.read_capacity,
|
39
|
-
:range_key =>
|
45
|
+
:range_key => range_key_hash
|
40
46
|
}.merge(options)
|
41
|
-
|
47
|
+
|
42
48
|
return true if table_exists?(options[:table_name])
|
43
|
-
|
49
|
+
|
44
50
|
Dynamoid::Adapter.tables << options[:table_name] if Dynamoid::Adapter.create_table(options[:table_name], options[:id], options)
|
45
51
|
end
|
46
52
|
|
47
53
|
# Does a table with this name exist?
|
48
54
|
#
|
49
|
-
# @since 0.2.0
|
55
|
+
# @since 0.2.0
|
50
56
|
def table_exists?(table_name)
|
51
57
|
Dynamoid::Adapter.tables.include?(table_name)
|
52
58
|
end
|
53
|
-
|
59
|
+
|
54
60
|
# Undump an object into a hash, converting each type from a string representation of itself into the type specified by the field.
|
55
61
|
#
|
56
62
|
# @since 0.2.0
|
@@ -58,20 +64,20 @@ module Dynamoid
|
|
58
64
|
incoming = (incoming || {}).symbolize_keys
|
59
65
|
Hash.new.tap do |hash|
|
60
66
|
self.attributes.each do |attribute, options|
|
61
|
-
hash[attribute] = undump_field(incoming[attribute], options
|
67
|
+
hash[attribute] = undump_field(incoming[attribute], options)
|
62
68
|
end
|
63
69
|
incoming.each {|attribute, value| hash[attribute] ||= value }
|
64
70
|
end
|
65
71
|
end
|
66
72
|
|
67
|
-
# Undump a value for a given type. Given a string, it'll determine (based on the type provided) whether to turn it into a
|
73
|
+
# Undump a value for a given type. Given a string, it'll determine (based on the type provided) whether to turn it into a
|
68
74
|
# string, integer, float, set, array, datetime, or serialized return value.
|
69
75
|
#
|
70
76
|
# @since 0.2.0
|
71
|
-
def undump_field(value,
|
77
|
+
def undump_field(value, options)
|
72
78
|
return if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
73
79
|
|
74
|
-
case type
|
80
|
+
case options[:type]
|
75
81
|
when :string
|
76
82
|
value.to_s
|
77
83
|
when :integer
|
@@ -92,7 +98,7 @@ module Dynamoid
|
|
92
98
|
end
|
93
99
|
when :serialized
|
94
100
|
if value.is_a?(String)
|
95
|
-
YAML.load(value)
|
101
|
+
options[:serializer] ? options[:serializer].load(value) : YAML.load(value)
|
96
102
|
else
|
97
103
|
value
|
98
104
|
end
|
@@ -100,14 +106,14 @@ module Dynamoid
|
|
100
106
|
end
|
101
107
|
|
102
108
|
end
|
103
|
-
|
109
|
+
|
104
110
|
# Is this object persisted in the datastore? Required for some ActiveModel integration stuff.
|
105
111
|
#
|
106
112
|
# @since 0.2.0
|
107
113
|
def persisted?
|
108
114
|
!new_record?
|
109
115
|
end
|
110
|
-
|
116
|
+
|
111
117
|
# Run the callbacks and then persist this object in the datastore.
|
112
118
|
#
|
113
119
|
# @since 0.2.0
|
@@ -142,28 +148,28 @@ module Dynamoid
|
|
142
148
|
delete_indexes
|
143
149
|
Dynamoid::Adapter.delete(self.class.table_name, self.id)
|
144
150
|
end
|
145
|
-
|
151
|
+
|
146
152
|
# Dump this object's attributes into hash form, fit to be persisted into the datastore.
|
147
153
|
#
|
148
154
|
# @since 0.2.0
|
149
155
|
def dump
|
150
156
|
Hash.new.tap do |hash|
|
151
157
|
self.class.attributes.each do |attribute, options|
|
152
|
-
hash[attribute] = dump_field(self.read_attribute(attribute), options
|
158
|
+
hash[attribute] = dump_field(self.read_attribute(attribute), options)
|
153
159
|
end
|
154
160
|
end
|
155
161
|
end
|
156
|
-
|
162
|
+
|
157
163
|
private
|
158
164
|
|
159
|
-
# Determine how to dump this field. Given a value, it'll determine how to turn it into a value that can be
|
165
|
+
# Determine how to dump this field. Given a value, it'll determine how to turn it into a value that can be
|
160
166
|
# persisted into the datastore.
|
161
167
|
#
|
162
168
|
# @since 0.2.0
|
163
|
-
def dump_field(value,
|
169
|
+
def dump_field(value, options)
|
164
170
|
return if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
165
171
|
|
166
|
-
case type
|
172
|
+
case options[:type]
|
167
173
|
when :string
|
168
174
|
value.to_s
|
169
175
|
when :integer
|
@@ -179,11 +185,11 @@ module Dynamoid
|
|
179
185
|
when :datetime
|
180
186
|
value.to_time.to_f
|
181
187
|
when :serialized
|
182
|
-
value.to_yaml
|
188
|
+
options[:serializer] ? options[:serializer].dump(value) : value.to_yaml
|
183
189
|
end
|
184
190
|
end
|
185
191
|
|
186
|
-
# Persist the object into the datastore. Assign it an id first if it doesn't have one; then afterwards,
|
192
|
+
# Persist the object into the datastore. Assign it an id first if it doesn't have one; then afterwards,
|
187
193
|
# save its indexes.
|
188
194
|
#
|
189
195
|
# @since 0.2.0
|
@@ -196,7 +202,7 @@ module Dynamoid
|
|
196
202
|
true
|
197
203
|
end
|
198
204
|
end
|
199
|
-
|
205
|
+
|
200
206
|
end
|
201
|
-
|
207
|
+
|
202
208
|
end
|