dynamodb_framework 0.1.4 → 1.0.0
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.
- checksums.yaml +4 -4
- data/.idea/workspace.xml +306 -137
- data/README.md +13 -13
- data/dynamodb_framework.gemspec +1 -1
- data/lib/dynamodb_framework.rb +11 -7
- data/lib/dynamodb_framework/dynamodb_attributes_builder.rb +60 -16
- data/lib/dynamodb_framework/dynamodb_logger.rb +7 -0
- data/lib/dynamodb_framework/dynamodb_migration_manager.rb +63 -61
- data/lib/dynamodb_framework/dynamodb_migration_script.rb +13 -12
- data/lib/dynamodb_framework/dynamodb_repository.rb +158 -131
- data/lib/dynamodb_framework/dynamodb_store.rb +13 -13
- data/lib/dynamodb_framework/dynamodb_table_manager.rb +267 -198
- data/lib/dynamodb_framework/version.rb +2 -2
- data/script/cleanup.sh +6 -0
- data/script/container_loop.sh +6 -0
- data/script/docker-compose.yml +5 -0
- data/script/restart.sh +3 -0
- data/script/start.sh +4 -0
- data/script/stop.sh +2 -0
- metadata +32 -26
data/README.md
CHANGED
@@ -25,7 +25,7 @@ To create or modify a DynamoDb instance you first need to create a migration scr
|
|
25
25
|
|
26
26
|
**Example**
|
27
27
|
|
28
|
-
class CreateEventTrackingTableScript < MigrationScript
|
28
|
+
class CreateEventTrackingTableScript < DynamoDbFramework::MigrationScript
|
29
29
|
|
30
30
|
def initialize
|
31
31
|
#set the timestamp for when this script was created
|
@@ -34,9 +34,9 @@ To create or modify a DynamoDb instance you first need to create a migration scr
|
|
34
34
|
|
35
35
|
def apply
|
36
36
|
#create an instance of the table manager
|
37
|
-
manager =
|
37
|
+
manager = DynamoDbFramework::TableManager.new
|
38
38
|
#create an attribute builder
|
39
|
-
builder =
|
39
|
+
builder = DynamoDbFramework::AttributesBuilder.new
|
40
40
|
|
41
41
|
#set the hash key attribute
|
42
42
|
builder.add(:type, :S)
|
@@ -47,7 +47,7 @@ To create or modify a DynamoDb instance you first need to create a migration scr
|
|
47
47
|
def undo
|
48
48
|
|
49
49
|
#create an instance of the table manager
|
50
|
-
manager =
|
50
|
+
manager = DynamoDbFramework::TableManager.new
|
51
51
|
|
52
52
|
#drop the table
|
53
53
|
manager.drop('event_tracking')
|
@@ -75,7 +75,7 @@ This method is called to connect the manager to the DynamoDb instance. If the mi
|
|
75
75
|
|
76
76
|
**Example**
|
77
77
|
|
78
|
-
manager =
|
78
|
+
manager = DynamoDbFramework::MigrationManager.new
|
79
79
|
manager.connect
|
80
80
|
|
81
81
|
### #apply
|
@@ -92,7 +92,7 @@ This method is called to rollback the last migration script that was executed ag
|
|
92
92
|
#rollback the last migration script
|
93
93
|
manager.rollback
|
94
94
|
|
95
|
-
#
|
95
|
+
# DynamoDbFramework::TableManager
|
96
96
|
|
97
97
|
This manager object provides the following methods for managing tables within a DynamoDb instance.
|
98
98
|
|
@@ -103,7 +103,7 @@ This method is called to create a table within DynamoDb.
|
|
103
103
|
**Params**
|
104
104
|
|
105
105
|
- **table_name** [String] [Required] This is used to specify the name of the table to create. (Must be unique within the DynamoDb instance).
|
106
|
-
- **attributes** [Hash] [Required] This is used to specify the attributes used by the keys and indexes. (Use the
|
106
|
+
- **attributes** [Hash] [Required] This is used to specify the attributes used by the keys and indexes. (Use the DynamoDbFramework::AttributesBuilder to create attributes)
|
107
107
|
- **partition_key** [Symbol] [Required] This is the document attribute that will be used as the partition key of this table.
|
108
108
|
- **range_key** [Symbol / nil] [Optional] This is the document attribute that will be used as the range key for this table.
|
109
109
|
- **read_capacity** [Number] [Default=20] This is the read throughput required for this table.
|
@@ -115,7 +115,7 @@ This method is called to create a table within DynamoDb.
|
|
115
115
|
Table with partition key, no range key and no indexes:
|
116
116
|
|
117
117
|
#create an attribute builder
|
118
|
-
builder =
|
118
|
+
builder = DynamoDbFramework::AttributesBuilder.new
|
119
119
|
|
120
120
|
#set the partition key attribute
|
121
121
|
builder.add(:type, :S)
|
@@ -126,7 +126,7 @@ Table with partition key, no range key and no indexes:
|
|
126
126
|
Table with partition key, range key and no indexes:
|
127
127
|
|
128
128
|
#create an attribute builder
|
129
|
-
builder =
|
129
|
+
builder = DynamoDbFramework::AttributesBuilder.new
|
130
130
|
|
131
131
|
#set the partition key attribute
|
132
132
|
builder.add(:type, :S)
|
@@ -139,7 +139,7 @@ Table with partition key, range key and no indexes:
|
|
139
139
|
Table with a global index:
|
140
140
|
|
141
141
|
#create an attribute builder
|
142
|
-
builder =
|
142
|
+
builder = DynamoDbFramework::AttributesBuilder.new
|
143
143
|
|
144
144
|
#set the partition key attribute
|
145
145
|
builder.add(:id, :S)
|
@@ -181,13 +181,13 @@ This method is called to add an index to an existing table.
|
|
181
181
|
**Params**
|
182
182
|
|
183
183
|
- **table_name** [String] [Required] This is the name of the index. (Must be unique within the scope of the table)
|
184
|
-
- **attributes** [Hash] [Required] This is the document attributes used by the table keys and index keys. (Use the
|
184
|
+
- **attributes** [Hash] [Required] This is the document attributes used by the table keys and index keys. (Use the DynamoDbFramework::AttributesBuilder to create the attributes hash.)
|
185
185
|
- **global_index** [Hash] [Required] This is the global index to add to the table. (Use the ***#create_global_index*** method to create the global index hash.)
|
186
186
|
|
187
187
|
**Example**
|
188
188
|
|
189
189
|
#build the attributes hash
|
190
|
-
builder =
|
190
|
+
builder = DynamoDbFramework::AttributesBuilder.new
|
191
191
|
#add the attribute for the tables partition key & range key (if range key required)
|
192
192
|
builder.add(:id, :S)
|
193
193
|
#add the attributes for the index partition key and range key (if required)
|
@@ -237,7 +237,7 @@ This method is called to check if an index exists on a table within the database
|
|
237
237
|
=> true
|
238
238
|
|
239
239
|
|
240
|
-
#
|
240
|
+
# DynamoDbFramework::Repository
|
241
241
|
|
242
242
|
This is a base repository that exposes core functionality for interacting with a DynamoDb table. It is intended to be wrapped inside of a table specific repository, and is only provided to give a common way of interacting with a DynamoDb table.
|
243
243
|
|
data/dynamodb_framework.gemspec
CHANGED
@@ -5,7 +5,7 @@ require 'dynamodb_framework/version'
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "dynamodb_framework"
|
8
|
-
spec.version =
|
8
|
+
spec.version = DynamoDbFramework::VERSION
|
9
9
|
spec.authors = ["vaughanbrittonsage"]
|
10
10
|
spec.email = ["vaughanbritton@gmail.com"]
|
11
11
|
|
data/lib/dynamodb_framework.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
require_relative 'dynamodb_framework/version'
|
2
|
+
require_relative 'dynamodb_framework/dynamodb_attributes_builder'
|
3
|
+
require_relative 'dynamodb_framework/dynamodb_store'
|
4
|
+
require_relative 'dynamodb_framework/dynamodb_table_manager'
|
5
|
+
require_relative 'dynamodb_framework/dynamodb_repository'
|
6
|
+
require_relative 'dynamodb_framework/dynamodb_migration_manager'
|
7
|
+
require_relative 'dynamodb_framework/dynamodb_migration_script'
|
8
|
+
require_relative 'dynamodb_framework/dynamodb_logger'
|
9
|
+
|
10
|
+
require 'date'
|
11
|
+
|
@@ -1,20 +1,64 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module DynamoDbFramework
|
2
|
+
class AttributesBuilder
|
3
|
+
attr_reader :attributes
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def initialize
|
6
|
+
@attributes = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def add_from_args(name, type, key = nil)
|
10
|
+
type_symbol = :S
|
11
|
+
if type == 'number' || type == :N || type == :number
|
12
|
+
type_symbol = :N
|
13
|
+
elsif type == 'binary' || type == :B || type == :binary
|
14
|
+
type_symbol = :B
|
15
|
+
elsif type == 'bool' || type == 'boolean' || type == :BOOL || type == :bool || type == :boolean
|
16
|
+
type_symbol = :BOOL
|
17
|
+
end
|
18
|
+
|
19
|
+
if key == 'hash' || key == :hash
|
20
|
+
key = :hash
|
21
|
+
elsif key == 'range' || key == :range
|
22
|
+
key = :range
|
23
|
+
else
|
24
|
+
key = nil
|
25
|
+
end
|
7
26
|
|
8
|
-
|
9
|
-
type_symbol = :S
|
10
|
-
if type == 'number' || type == :N
|
11
|
-
type_symbol = :N
|
12
|
-
elsif type == 'binary' || type == :B
|
13
|
-
type_symbol = :B
|
14
|
-
elsif type == 'bool' || type == 'boolean' || type == :BOOL
|
15
|
-
type_symbol = :BOOL
|
27
|
+
@attributes.push({ :name => name, :type => type_symbol, :key => key })
|
16
28
|
end
|
17
|
-
@attributes.push({ :name => name, :type => type_symbol })
|
18
|
-
end
|
19
29
|
|
20
|
-
|
30
|
+
def add_from_hash(options)
|
31
|
+
type_symbol = :S
|
32
|
+
if options[:type] == 'number' || options[:type] == :N || options[:type] == :number
|
33
|
+
type_symbol = :N
|
34
|
+
elsif options[:type] == 'binary' || options[:type] == :B || options[:type] == :binary
|
35
|
+
type_symbol = :B
|
36
|
+
elsif options[:type] == 'bool' || options[:type] == 'boolean' || options[:type] == :BOOL || options[:type] == :bool || options[:type] == :boolean
|
37
|
+
type_symbol = :BOOL
|
38
|
+
end
|
39
|
+
|
40
|
+
if options[:key] == 'hash' || options[:key] == :hash
|
41
|
+
key = :hash
|
42
|
+
elsif options[:key] == 'range' || options[:key] == :range
|
43
|
+
key = :range
|
44
|
+
else
|
45
|
+
key = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
@attributes.push({ :name => options[:name], :type => type_symbol, :key => key })
|
49
|
+
end
|
50
|
+
|
51
|
+
def add(*options)
|
52
|
+
|
53
|
+
if options.length == 1 && options[0].is_a?(Hash)
|
54
|
+
add_from_hash(options[0])
|
55
|
+
elsif options.length == 3
|
56
|
+
add_from_args(options[0], options[1], options[2])
|
57
|
+
else
|
58
|
+
add_from_args(options[0], options[1])
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -1,89 +1,91 @@
|
|
1
|
-
|
1
|
+
module DynamoDbFramework
|
2
|
+
class MigrationManager
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
attr_reader :dynamodb_table_manager
|
5
|
+
attr_reader :dynamodb_repository
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def connect
|
7
|
+
def initialize(store)
|
8
|
+
@dynamodb_repository = DynamoDbFramework::Repository.new(store)
|
9
|
+
@dynamodb_table_manager = DynamoDbFramework::TableManager.new(store)
|
10
|
+
end
|
12
11
|
|
13
|
-
|
12
|
+
def connect
|
14
13
|
|
15
|
-
|
14
|
+
DynamoDbFramework::LOGGER.info '[DynamoDbFramework] - Connecting to DynamoDb instance'
|
16
15
|
|
17
|
-
|
18
|
-
if !@dynamodb_table_manager.exists?(migration_table_name)
|
19
|
-
#migration table not found so create it
|
20
|
-
builder = DynamoDbAttributesBuilder.new
|
21
|
-
builder.add(:timestamp, :S)
|
22
|
-
@dynamodb_table_manager.create(migration_table_name, builder.attributes, :timestamp)
|
23
|
-
end
|
16
|
+
migration_table_name = 'dynamodb_framework_migrations'
|
24
17
|
|
25
|
-
|
26
|
-
|
18
|
+
#check if migration table exists
|
19
|
+
if !@dynamodb_table_manager.exists?(migration_table_name)
|
20
|
+
#migration table not found so create it
|
21
|
+
builder = DynamoDbFramework::AttributesBuilder.new
|
22
|
+
builder.add(:timestamp, :S)
|
23
|
+
@dynamodb_table_manager.create(migration_table_name, builder.attributes, :timestamp)
|
24
|
+
end
|
27
25
|
|
28
|
-
|
26
|
+
#set the table name for the repository
|
27
|
+
@dynamodb_repository.table_name = migration_table_name
|
29
28
|
|
30
|
-
|
29
|
+
DynamoDbFramework::LOGGER.info '[DynamoDbFramework] - Connected.'
|
31
30
|
|
32
|
-
def get_executed_scripts
|
33
|
-
scripts = @dynamodb_repository.all()
|
34
|
-
if scripts.length > 0
|
35
|
-
return scripts.sort { |a,b| b['timestamp'] <=> a['timestamp'] }.map { |i| i['timestamp'] }
|
36
31
|
end
|
37
32
|
|
38
|
-
|
39
|
-
|
33
|
+
def get_executed_scripts
|
34
|
+
scripts = @dynamodb_repository.all()
|
35
|
+
if scripts.length > 0
|
36
|
+
return scripts.sort { |a,b| b['timestamp'] <=> a['timestamp'] }.map { |i| i['timestamp'] }
|
37
|
+
end
|
40
38
|
|
41
|
-
|
39
|
+
return nil
|
40
|
+
end
|
42
41
|
|
43
|
-
|
42
|
+
def apply
|
44
43
|
|
45
|
-
|
44
|
+
DynamoDbFramework::LOGGER.info '[DynamoDbFramework] - Applying migration scripts'
|
46
45
|
|
47
|
-
|
48
|
-
MigrationScript.descendants.each do |ms|
|
49
|
-
script = ms.new
|
50
|
-
scripts.push(script)
|
51
|
-
end
|
46
|
+
executed_scripts = get_executed_scripts()
|
52
47
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
script
|
57
|
-
@dynamodb_repository.put({ :timestamp => script.timestamp })
|
48
|
+
scripts = []
|
49
|
+
DynamoDbFramework::MigrationScript.descendants.each do |ms|
|
50
|
+
script = ms.new
|
51
|
+
scripts.push(script)
|
58
52
|
end
|
59
|
-
end
|
60
53
|
|
61
|
-
|
54
|
+
scripts.sort { |a,b| a.timestamp <=> b.timestamp }.each do |script|
|
55
|
+
if executed_scripts == nil || !executed_scripts.include?(script.timestamp)
|
56
|
+
DynamoDbFramework::LOGGER.info '[DynamoDbFramework] - Applying script: ' + script.timestamp + '.....'
|
57
|
+
script.apply
|
58
|
+
@dynamodb_repository.put({ :timestamp => script.timestamp })
|
59
|
+
end
|
60
|
+
end
|
62
61
|
|
63
|
-
|
62
|
+
DynamoDbFramework::LOGGER.info '[DynamoDbFramework] - Migration scripts applied.'
|
64
63
|
|
65
|
-
|
64
|
+
end
|
66
65
|
|
67
|
-
|
66
|
+
def rollback
|
68
67
|
|
69
|
-
|
68
|
+
DynamoDbFramework::LOGGER.info '[DynamoDbFramework] - Rolling back started.'
|
70
69
|
|
71
|
-
|
72
|
-
MigrationScript.descendants.each do |ms|
|
73
|
-
script = ms.new
|
74
|
-
scripts.push(script)
|
75
|
-
end
|
70
|
+
executed_scripts = get_executed_scripts()
|
76
71
|
|
77
|
-
|
78
|
-
|
79
|
-
script.
|
80
|
-
|
81
|
-
return
|
72
|
+
scripts = []
|
73
|
+
DynamoDbFramework::MigrationScript.descendants.each do |ms|
|
74
|
+
script = ms.new
|
75
|
+
scripts.push(script)
|
82
76
|
end
|
83
|
-
end
|
84
77
|
|
85
|
-
|
78
|
+
scripts.sort { |a,b| a.timestamp <=> b.timestamp }.each do |script|
|
79
|
+
if executed_scripts != nil && executed_scripts.length > 0 && executed_scripts.include?(script.timestamp)
|
80
|
+
script.undo
|
81
|
+
@dynamodb_repository.delete({ :timestamp => script.timestamp })
|
82
|
+
return
|
83
|
+
end
|
84
|
+
end
|
86
85
|
|
87
|
-
|
86
|
+
DynamoDbFramework::LOGGER.info '[DynamoDbFramework] - Rollback complete.'
|
88
87
|
|
89
|
-
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
@@ -1,16 +1,17 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module DynamoDbFramework
|
2
|
+
class MigrationScript
|
3
|
+
attr_accessor :timestamp
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def apply
|
6
|
+
raise 'Not implemented.'
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def undo
|
10
|
+
raise 'Not implemented.'
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
def self.descendants
|
14
|
+
ObjectSpace.each_object(Class).select { |klass| klass < self }
|
15
|
+
end
|
14
16
|
end
|
15
|
-
|
16
|
-
end
|
17
|
+
end
|
@@ -1,193 +1,220 @@
|
|
1
|
-
|
1
|
+
require 'date'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
module DynamoDbFramework
|
4
|
+
class Repository
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
end
|
6
|
+
attr_reader :dynamodb
|
7
|
+
attr_accessor :table_name
|
9
8
|
|
10
|
-
|
9
|
+
def initialize(store)
|
10
|
+
@dynamodb = store
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
json_obj = JSON.load(json_string)
|
13
|
+
def put(item)
|
14
14
|
|
15
|
-
|
16
|
-
{
|
17
|
-
table_name: @table_name,
|
18
|
-
item: json_obj
|
19
|
-
}
|
15
|
+
hash = to_hash(item)
|
20
16
|
|
21
|
-
|
17
|
+
params =
|
18
|
+
{
|
19
|
+
table_name: @table_name,
|
20
|
+
item: hash
|
21
|
+
}
|
22
22
|
|
23
|
-
|
23
|
+
dynamodb.client.put_item(params)
|
24
24
|
|
25
|
-
|
25
|
+
return true
|
26
26
|
|
27
|
-
|
28
|
-
{
|
29
|
-
table_name: @table_name,
|
30
|
-
key: keys
|
31
|
-
}
|
27
|
+
end
|
32
28
|
|
33
|
-
|
29
|
+
def delete(keys)
|
34
30
|
|
35
|
-
|
31
|
+
params =
|
32
|
+
{
|
33
|
+
table_name: @table_name,
|
34
|
+
key: keys
|
35
|
+
}
|
36
36
|
|
37
|
-
|
37
|
+
dynamodb.client.delete_item(params)
|
38
38
|
|
39
|
-
|
40
|
-
key[partition_key] = partition_value
|
41
|
-
if(range_key != nil)
|
42
|
-
key[range_key] = range_value
|
43
|
-
end
|
39
|
+
return true
|
44
40
|
|
45
|
-
|
46
|
-
table_name: table_name,
|
47
|
-
key: key
|
48
|
-
}
|
41
|
+
end
|
49
42
|
|
50
|
-
|
51
|
-
return map(result.item)
|
43
|
+
def get_by_key(partition_key, partition_value, range_key = nil, range_value = nil)
|
52
44
|
|
53
|
-
|
45
|
+
key = {}
|
46
|
+
key[partition_key] = partition_value
|
47
|
+
if(range_key != nil)
|
48
|
+
key[range_key] = range_value
|
49
|
+
end
|
54
50
|
|
55
|
-
|
51
|
+
params = {
|
52
|
+
table_name: table_name,
|
53
|
+
key: key
|
54
|
+
}
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
})
|
56
|
+
result = dynamodb.client.get_item(params)
|
57
|
+
return result.item
|
60
58
|
|
61
|
-
output = []
|
62
|
-
result.items.each do |item|
|
63
|
-
output.push(map(item))
|
64
59
|
end
|
65
60
|
|
66
|
-
|
61
|
+
def all
|
67
62
|
|
68
|
-
|
63
|
+
result = dynamodb.client.scan({
|
64
|
+
:table_name => @table_name
|
65
|
+
})
|
69
66
|
|
70
|
-
|
67
|
+
output = []
|
68
|
+
result.items.each do |item|
|
69
|
+
output.push(item)
|
70
|
+
end
|
71
71
|
|
72
|
-
|
73
|
-
:table_name => table_name
|
74
|
-
}
|
72
|
+
return output
|
75
73
|
|
76
|
-
if expression != nil
|
77
|
-
params[:filter_expression] = expression
|
78
74
|
end
|
79
75
|
|
80
|
-
|
76
|
+
def scan(expression, expression_params, limit = nil, count = false)
|
81
77
|
|
82
|
-
params
|
83
|
-
|
78
|
+
params = {
|
79
|
+
:table_name => table_name
|
80
|
+
}
|
84
81
|
|
85
|
-
|
86
|
-
|
87
|
-
params[:expression_attribute_names][key] = value
|
88
|
-
elsif key.starts_with?(':')
|
89
|
-
params[:expression_attribute_values][key] = value
|
90
|
-
end
|
82
|
+
if expression != nil
|
83
|
+
params[:filter_expression] = expression
|
91
84
|
end
|
92
85
|
|
93
|
-
|
86
|
+
if expression_params != nil
|
94
87
|
|
95
|
-
|
96
|
-
|
97
|
-
end
|
88
|
+
params[:expression_attribute_names] = {}
|
89
|
+
params[:expression_attribute_values] = {}
|
98
90
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
91
|
+
expression_params.each do |key, value|
|
92
|
+
if key[0] == '#'
|
93
|
+
params[:expression_attribute_names][key] = value
|
94
|
+
elsif key[0] == ':'
|
95
|
+
params[:expression_attribute_values][key] = value
|
96
|
+
end
|
97
|
+
end
|
104
98
|
|
105
|
-
|
99
|
+
end
|
106
100
|
|
107
|
-
|
108
|
-
|
109
|
-
else
|
110
|
-
output = []
|
111
|
-
result.items.each do |item|
|
112
|
-
output.push(map(item))
|
101
|
+
if limit != nil
|
102
|
+
params[:limit] = limit
|
113
103
|
end
|
114
104
|
|
115
|
-
|
116
|
-
|
105
|
+
if count
|
106
|
+
params[:select] = 'COUNT'
|
107
|
+
else
|
108
|
+
params[:select] = 'ALL_ATTRIBUTES'
|
109
|
+
end
|
117
110
|
|
118
|
-
|
111
|
+
result = dynamodb.client.scan(params)
|
119
112
|
|
120
|
-
|
113
|
+
if count
|
114
|
+
return result.count
|
115
|
+
else
|
116
|
+
output = []
|
117
|
+
result.items.each do |item|
|
118
|
+
output.push(item)
|
119
|
+
end
|
121
120
|
|
122
|
-
|
123
|
-
|
124
|
-
}
|
121
|
+
return output
|
122
|
+
end
|
125
123
|
|
126
|
-
if expression != nil
|
127
|
-
params[:filter_expression] = expression
|
128
124
|
end
|
129
125
|
|
130
|
-
|
131
|
-
params[:index_name] = index_name
|
132
|
-
end
|
126
|
+
def query(partition_key_name, partition_key_value, range_key_name = nil, range_key_value = nil, expression = nil, expression_params = nil, index_name = nil, limit = nil, count = false)
|
133
127
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
params[:expression_attribute_values] = { ':partition_key' => partition_key_value }
|
142
|
-
end
|
128
|
+
params = {
|
129
|
+
table_name: table_name
|
130
|
+
}
|
131
|
+
|
132
|
+
if expression != nil
|
133
|
+
params[:filter_expression] = expression
|
134
|
+
end
|
143
135
|
|
144
|
-
|
136
|
+
if index_name != nil
|
137
|
+
params[:index_name] = index_name
|
138
|
+
end
|
139
|
+
|
140
|
+
if range_key_name != nil
|
141
|
+
params[:key_condition_expression] = '#partition_key = :partition_key and #range_key = :range_key'
|
142
|
+
params[:expression_attribute_names] = { '#partition_key' => partition_key_name, '#range_key' => range_key_name }
|
143
|
+
params[:expression_attribute_values] = { ':partition_key' => partition_key_value, ':range_key' => range_key_value }
|
144
|
+
else
|
145
|
+
params[:key_condition_expression] = '#partition_key = :partition_key'
|
146
|
+
params[:expression_attribute_names] = { '#partition_key' => partition_key_name }
|
147
|
+
params[:expression_attribute_values] = { ':partition_key' => partition_key_value }
|
148
|
+
end
|
145
149
|
|
146
|
-
expression_params
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
150
|
+
if expression_params != nil
|
151
|
+
expression_params.each do |key, value|
|
152
|
+
if key[0] == '#'
|
153
|
+
params[:expression_attribute_names][key] = value
|
154
|
+
elsif key[0] == ':'
|
155
|
+
params[:expression_attribute_values][key] = value
|
156
|
+
end
|
151
157
|
end
|
158
|
+
|
152
159
|
end
|
153
160
|
|
154
|
-
|
161
|
+
if limit != nil
|
162
|
+
params[:limit] = limit
|
163
|
+
end
|
155
164
|
|
156
|
-
|
157
|
-
|
158
|
-
|
165
|
+
if count
|
166
|
+
params[:select] = 'COUNT'
|
167
|
+
else
|
168
|
+
params[:select] = 'ALL_ATTRIBUTES'
|
169
|
+
end
|
159
170
|
|
160
|
-
|
161
|
-
params[:select] = 'COUNT'
|
162
|
-
else
|
163
|
-
params[:select] = 'ALL_ATTRIBUTES'
|
164
|
-
end
|
171
|
+
result = dynamodb.client.query(params)
|
165
172
|
|
166
|
-
|
173
|
+
if count
|
174
|
+
return result.count
|
175
|
+
else
|
176
|
+
output = []
|
177
|
+
result.items.each do |item|
|
178
|
+
output.push(item)
|
179
|
+
end
|
167
180
|
|
168
|
-
|
169
|
-
return result.count
|
170
|
-
else
|
171
|
-
output = []
|
172
|
-
result.items.each do |item|
|
173
|
-
output.push(map(item))
|
181
|
+
return output
|
174
182
|
end
|
175
183
|
|
176
|
-
return output
|
177
184
|
end
|
178
185
|
|
179
|
-
|
186
|
+
private
|
180
187
|
|
181
|
-
|
182
|
-
|
183
|
-
|
188
|
+
def to_hashb(obj)
|
189
|
+
hash = {}
|
190
|
+
obj.instance_variables.each {|var| hash[var.to_s.delete("@")] = obj.instance_variable_get(var) }
|
191
|
+
hash
|
192
|
+
end
|
193
|
+
|
194
|
+
STANDARD_TYPES = [String, Numeric, Fixnum, Integer, Float, nil, Time, Date, DateTime].freeze
|
184
195
|
|
185
|
-
|
196
|
+
def is_standard_type?(obj)
|
197
|
+
return STANDARD_TYPES.detect { |type| obj.is_a?(type) } != nil
|
198
|
+
end
|
199
|
+
|
200
|
+
def to_hash(obj)
|
201
|
+
if obj.is_a?(Hash)
|
202
|
+
return obj
|
203
|
+
end
|
204
|
+
|
205
|
+
hash = {}
|
206
|
+
obj.instance_variables.each do |var|
|
207
|
+
value = obj.instance_variable_get(var)
|
208
|
+
if value.is_a?(Array)
|
209
|
+
hash[var.to_s.delete("@")] = value.collect { |i| to_hash(i) }
|
210
|
+
elsif !is_standard_type?(value)
|
211
|
+
hash[var.to_s.delete("@")] = to_hash(value)
|
212
|
+
else
|
213
|
+
hash[var.to_s.delete("@")] = value
|
214
|
+
end
|
215
|
+
end
|
216
|
+
hash
|
217
|
+
end
|
186
218
|
|
187
|
-
class ::Hash
|
188
|
-
def method_missing(name)
|
189
|
-
return self[name] if key? name
|
190
|
-
self.each { |k,v| return v if k.to_s.to_sym == name }
|
191
|
-
super.method_missing name
|
192
219
|
end
|
193
220
|
end
|