commutator 0.1.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 +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Changelog.md +15 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +55 -0
- data/README.md +86 -0
- data/Rakefile +6 -0
- data/bin/console +26 -0
- data/bin/setup +8 -0
- data/commutator.gemspec +29 -0
- data/lib/commutator/collection.rb +78 -0
- data/lib/commutator/expressions/attribute_names.rb +24 -0
- data/lib/commutator/expressions/attribute_values.rb +21 -0
- data/lib/commutator/expressions/condition_expression.rb +101 -0
- data/lib/commutator/expressions/projection_expression.rb +50 -0
- data/lib/commutator/expressions/statement.rb +38 -0
- data/lib/commutator/expressions/update_expression.rb +61 -0
- data/lib/commutator/item_modifiers.rb +24 -0
- data/lib/commutator/model/attributes.rb +72 -0
- data/lib/commutator/model/hooks.rb +41 -0
- data/lib/commutator/model/table_configuration.rb +41 -0
- data/lib/commutator/model.rb +239 -0
- data/lib/commutator/options/delete_item.rb +48 -0
- data/lib/commutator/options/get_item.rb +41 -0
- data/lib/commutator/options/proxy.rb +90 -0
- data/lib/commutator/options/put_item.rb +46 -0
- data/lib/commutator/options/query.rb +73 -0
- data/lib/commutator/options/scan.rb +60 -0
- data/lib/commutator/options/update_item.rb +55 -0
- data/lib/commutator/simple_client.rb +27 -0
- data/lib/commutator/util/fluent.rb +67 -0
- data/lib/commutator/util/placeholders.rb +607 -0
- data/lib/commutator/version.rb +3 -0
- data/lib/commutator.rb +64 -0
- metadata +178 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
module Commutator
|
2
|
+
module Options
|
3
|
+
class Query
|
4
|
+
include Util::Fluent
|
5
|
+
|
6
|
+
fluent_accessor :key_condition_expression,
|
7
|
+
:filter_expression,
|
8
|
+
:projection_expression,
|
9
|
+
:consistent_read,
|
10
|
+
:expression_attribute_values,
|
11
|
+
:expression_attribute_names,
|
12
|
+
:exclusive_start_key,
|
13
|
+
:index_name,
|
14
|
+
:return_consumed_capacity,
|
15
|
+
:scan_index_forward,
|
16
|
+
:select,
|
17
|
+
:table_name,
|
18
|
+
:limit
|
19
|
+
|
20
|
+
fluent_wrapper :key_condition_expression,
|
21
|
+
:filter_expression,
|
22
|
+
:projection_expression,
|
23
|
+
:expression_attribute_values,
|
24
|
+
:expression_attribute_names,
|
25
|
+
:exclusive_start_key
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@expression_attribute_values ||= Expressions::AttributeValues.new
|
29
|
+
@expression_attribute_names ||= Expressions::AttributeNames.new
|
30
|
+
|
31
|
+
@key_condition_expression ||= Expressions::ConditionExpression.new(
|
32
|
+
attribute_names: @expression_attribute_names,
|
33
|
+
attribute_values: @expression_attribute_values)
|
34
|
+
|
35
|
+
@filter_expression ||= Expressions::ConditionExpression.new(
|
36
|
+
attribute_names: @expression_attribute_names,
|
37
|
+
attribute_values: @expression_attribute_values)
|
38
|
+
|
39
|
+
@projection_expression ||= Expressions::ProjectionExpression.new(
|
40
|
+
attribute_names: @expression_attribute_names)
|
41
|
+
end
|
42
|
+
|
43
|
+
def asc
|
44
|
+
scan_index_forward(true)
|
45
|
+
end
|
46
|
+
|
47
|
+
def desc
|
48
|
+
scan_index_forward(false)
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_h
|
52
|
+
hash = {
|
53
|
+
table_name: table_name,
|
54
|
+
limit: limit,
|
55
|
+
consistent_read: consistent_read,
|
56
|
+
index_name: index_name,
|
57
|
+
select: select,
|
58
|
+
exclusive_start_key: exclusive_start_key,
|
59
|
+
scan_index_forward: scan_index_forward,
|
60
|
+
return_consumed_capacity: return_consumed_capacity,
|
61
|
+
projection_expression: projection_expression.to_s,
|
62
|
+
expression_attribute_names: expression_attribute_names.to_h,
|
63
|
+
expression_attribute_values: expression_attribute_values.to_h,
|
64
|
+
key_condition_expression: key_condition_expression.to_s(wrap: false),
|
65
|
+
filter_expression: filter_expression.to_s(wrap: false)
|
66
|
+
}
|
67
|
+
|
68
|
+
hash.keep_if { |_key, value| value.present? || value == false }
|
69
|
+
end
|
70
|
+
alias :to_hash :to_h
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Commutator
|
2
|
+
module Options
|
3
|
+
class Scan
|
4
|
+
include Util::Fluent
|
5
|
+
|
6
|
+
fluent_accessor :expression_attribute_values,
|
7
|
+
:expression_attribute_names,
|
8
|
+
:filter_expression,
|
9
|
+
:projection_expression,
|
10
|
+
:consistent_read,
|
11
|
+
:exclusive_start_key,
|
12
|
+
:index_name,
|
13
|
+
:limit,
|
14
|
+
:select,
|
15
|
+
:return_consumed_capacity,
|
16
|
+
:segment,
|
17
|
+
:table_name,
|
18
|
+
:total_segments
|
19
|
+
|
20
|
+
fluent_wrapper :expression_attribute_values,
|
21
|
+
:expression_attribute_names,
|
22
|
+
:filter_expression,
|
23
|
+
:projection_expression,
|
24
|
+
:exclusive_start_key
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@expression_attribute_values = Expressions::AttributeValues.new
|
28
|
+
@expression_attribute_names = Expressions::AttributeNames.new
|
29
|
+
|
30
|
+
@filter_expression = Expressions::ConditionExpression.new(
|
31
|
+
attribute_names: @expression_attribute_names,
|
32
|
+
attribute_values: @expression_attribute_values)
|
33
|
+
|
34
|
+
@projection_expression = Expressions::ProjectionExpression.new(
|
35
|
+
attribute_names: @expression_attribute_names)
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_h
|
39
|
+
hash = {
|
40
|
+
projection_expression: projection_expression.to_s,
|
41
|
+
expression_attribute_values: expression_attribute_values.to_h,
|
42
|
+
expression_attribute_names: expression_attribute_names.to_h,
|
43
|
+
filter_expression: filter_expression.to_s(wrap: false),
|
44
|
+
consistent_read: consistent_read,
|
45
|
+
exclusive_start_key: exclusive_start_key,
|
46
|
+
index_name: index_name,
|
47
|
+
limit: limit,
|
48
|
+
select: select,
|
49
|
+
return_consumed_capacity: return_consumed_capacity,
|
50
|
+
table_name: table_name,
|
51
|
+
total_segments: total_segments,
|
52
|
+
segment: segment
|
53
|
+
}
|
54
|
+
|
55
|
+
hash.keep_if { |_key, value| value.present? || value == false }
|
56
|
+
end
|
57
|
+
alias :to_hash :to_h
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Commutator
|
2
|
+
module Options
|
3
|
+
class UpdateItem
|
4
|
+
include Util::Fluent
|
5
|
+
|
6
|
+
fluent_accessor :key,
|
7
|
+
:expression_attribute_names,
|
8
|
+
:expression_attribute_values,
|
9
|
+
:update_expression,
|
10
|
+
:condition_expression,
|
11
|
+
:return_values,
|
12
|
+
:return_consumed_capacity,
|
13
|
+
:return_item_collection_metrics,
|
14
|
+
:table_name
|
15
|
+
|
16
|
+
fluent_wrapper :key,
|
17
|
+
:expression_attribute_names,
|
18
|
+
:expression_attribute_values,
|
19
|
+
:update_expression,
|
20
|
+
:condition_expression
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@key = {}
|
24
|
+
|
25
|
+
@expression_attribute_names = Expressions::AttributeNames.new
|
26
|
+
@expression_attribute_values = Expressions::AttributeValues.new
|
27
|
+
|
28
|
+
@update_expression = Expressions::UpdateExpression.new(
|
29
|
+
attribute_names: @expression_attribute_names,
|
30
|
+
attribute_values: @expression_attribute_values)
|
31
|
+
|
32
|
+
@condition_expression = Expressions::ConditionExpression.new(
|
33
|
+
attribute_names: @expression_attribute_names,
|
34
|
+
attribute_values: @expression_attribute_values)
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_h
|
38
|
+
hash = {
|
39
|
+
key: key,
|
40
|
+
expression_attribute_names: expression_attribute_names.to_h,
|
41
|
+
expression_attribute_values: expression_attribute_values.to_h,
|
42
|
+
condition_expression: condition_expression.to_s(wrap: false),
|
43
|
+
update_expression: update_expression.to_s,
|
44
|
+
return_values: return_values,
|
45
|
+
return_consumed_capacity: return_consumed_capacity,
|
46
|
+
return_item_collection_metrics: return_item_collection_metrics,
|
47
|
+
table_name: table_name
|
48
|
+
}
|
49
|
+
|
50
|
+
hash.keep_if { |_key, value| value.present? || value == false }
|
51
|
+
end
|
52
|
+
alias :to_hash :to_h
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Commutator
|
2
|
+
# Provides an instance of `Aws::DynamoDB::Client` with conversions for passing
|
3
|
+
# Commutator objects to API operations.
|
4
|
+
#
|
5
|
+
# `:client => ` may be provided as an `Aws::DynamoDB::Client` instance
|
6
|
+
# otherwise this instantiates a `Aws::DynamoDB::Client` with the provided options
|
7
|
+
class SimpleClient < SimpleDelegator
|
8
|
+
def initialize(client: nil, **options)
|
9
|
+
return super(client) if client
|
10
|
+
|
11
|
+
defaults = {
|
12
|
+
region: "us-east-1",
|
13
|
+
endpoint: "https://dynamodb.us-east-1.amazonaws.com",
|
14
|
+
}
|
15
|
+
options = defaults.merge options
|
16
|
+
|
17
|
+
super Aws::DynamoDB::Client.new(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
# `**kwargs` automatically calls `to_hash` on Options instances
|
21
|
+
API_OPERATIONS.each do |operation|
|
22
|
+
define_method(operation) do |**kwargs|
|
23
|
+
super kwargs
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Commutator
|
2
|
+
module Util
|
3
|
+
# This module provides fluent accessors and wrappers, which are probably
|
4
|
+
# just terms I made up.
|
5
|
+
#
|
6
|
+
# Usage:
|
7
|
+
# class Person
|
8
|
+
# include Commutator::Util::Fluent
|
9
|
+
#
|
10
|
+
# fluent_accessor :first_name,
|
11
|
+
# :last_name,
|
12
|
+
# :pets
|
13
|
+
#
|
14
|
+
# fluent_wrapper :pets
|
15
|
+
#
|
16
|
+
# def initialize
|
17
|
+
# @pets = []
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# When called with an argument a fluent accessor will set a value
|
22
|
+
# and return the instance again. This allows chaining.
|
23
|
+
#
|
24
|
+
# Ex:
|
25
|
+
# person = Person.new.first_name('Seymour').last_name('Busses')
|
26
|
+
# # => <#Person @first_name='Seymour', @last_name='Busses'>
|
27
|
+
#
|
28
|
+
# When called without an argument a fluent accessor will return the value
|
29
|
+
# it has.
|
30
|
+
# person = Person.new.first_name('Seymour')
|
31
|
+
# person.first_name # => 'Seymour'
|
32
|
+
#
|
33
|
+
# A fluent wrapper allows you to manipulate "complex" objects and continue
|
34
|
+
# to chain calls. Fluent wrappers start with a `with_` followed by the
|
35
|
+
# attribute name. Fluent wrapper passes the value into a block.
|
36
|
+
#
|
37
|
+
# Ex:
|
38
|
+
# person = Person.new
|
39
|
+
# .first_name('Hi')
|
40
|
+
# .with_pets { |pets| pets << 'mittens' }
|
41
|
+
#
|
42
|
+
module Fluent
|
43
|
+
extend ActiveSupport::Concern
|
44
|
+
|
45
|
+
module ClassMethods
|
46
|
+
def fluent_wrapper(*attr_names)
|
47
|
+
attr_names.each do |attr_name|
|
48
|
+
define_method "with_#{attr_name}" do |&block|
|
49
|
+
block.call(instance_variable_get("@#{attr_name}"))
|
50
|
+
self
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def fluent_accessor(*attr_names)
|
56
|
+
attr_names.each do |attr_name|
|
57
|
+
define_method attr_name do |*val|
|
58
|
+
return instance_variable_get("@#{attr_name}") if val.empty?
|
59
|
+
instance_variable_set("@#{attr_name}", val.first)
|
60
|
+
self
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|