dynamoid 0.4.0 → 0.4.1
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.
- 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
|