dynameek 0.0.1a → 0.1.1a
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/dynameek/model/dynamo_db.rb +57 -0
- data/lib/dynameek/model/query.rb +79 -0
- data/lib/dynameek/model/structure.rb +108 -0
- data/lib/dynameek/model.rb +10 -7
- data/lib/dynameek.rb +3 -3
- metadata +4 -4
- data/lib/dynameek/dynamo_db.rb +0 -58
- data/lib/dynameek/model_structure.rb +0 -106
- data/lib/dynameek/query.rb +0 -77
@@ -0,0 +1,57 @@
|
|
1
|
+
module Dynameek
|
2
|
+
module Model
|
3
|
+
module DynamoDb
|
4
|
+
def convert_from_dynamodb(type, value)
|
5
|
+
case type
|
6
|
+
when :integer
|
7
|
+
value.to_i
|
8
|
+
when :float
|
9
|
+
value.to_f
|
10
|
+
when :string
|
11
|
+
value.to_s
|
12
|
+
when :datetime
|
13
|
+
Time.at(value).to_datetime
|
14
|
+
else
|
15
|
+
value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
def convert_to_dynamodb(type, value)
|
19
|
+
case type
|
20
|
+
when :datetime
|
21
|
+
value.to_time.to_f
|
22
|
+
else
|
23
|
+
value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def exists?
|
28
|
+
table.exists?
|
29
|
+
end
|
30
|
+
|
31
|
+
def build!
|
32
|
+
return if dynamo_db.tables[table_name].exists?
|
33
|
+
new_table = dynamo_db.tables.create(table_name, @@read_write[0], @@read_write[1],
|
34
|
+
:hash_key => { hash_key_field.field => hash_key_field.type },
|
35
|
+
:range_key => { range_field.field => range_field.type == :datetime ? :number : range_field.type }
|
36
|
+
)
|
37
|
+
puts "Creating table, this may take a few minutes"
|
38
|
+
while new_table.status == :creating
|
39
|
+
sleep 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def dynamo_db
|
44
|
+
@dynamo_db ||= AWS::DynamoDB.new
|
45
|
+
@dynamo_db
|
46
|
+
end
|
47
|
+
|
48
|
+
def table
|
49
|
+
build!
|
50
|
+
@table ||= dynamo_db.tables[table_name]
|
51
|
+
@table.load_schema if !@table.schema_loaded?
|
52
|
+
@table
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Dynameek
|
2
|
+
module Model
|
3
|
+
module Query
|
4
|
+
#Similar to dynamoids approach but lighter (hopefully)
|
5
|
+
|
6
|
+
class QueryChain
|
7
|
+
|
8
|
+
def initialize(model)
|
9
|
+
@model = model
|
10
|
+
@hash_key = nil
|
11
|
+
@range = {eq: nil, within: nil, gte: nil, gt: nil, lte: nil, lt: nil, begins_with: nil}
|
12
|
+
end
|
13
|
+
|
14
|
+
def query(hash_key)
|
15
|
+
@hash_key = hash_key
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def where(value, op=:eq)
|
20
|
+
raise Exception("Op #{op.to_s} not recognised") if(!@range.keys.include?(op))
|
21
|
+
@range[op] = value
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def all
|
26
|
+
run
|
27
|
+
end
|
28
|
+
|
29
|
+
def each
|
30
|
+
all.each
|
31
|
+
end
|
32
|
+
|
33
|
+
def each_with_index
|
34
|
+
all.each_with_index
|
35
|
+
end
|
36
|
+
|
37
|
+
RANGE_QUERY_MAP =
|
38
|
+
{
|
39
|
+
eq: :range_value,
|
40
|
+
within: :range_value,
|
41
|
+
gte: :range_gte,
|
42
|
+
gt: :range_greater_than,
|
43
|
+
lte: :range_lte,
|
44
|
+
lt: :range_less_than,
|
45
|
+
begins_with: :range_begins_with
|
46
|
+
}
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def run
|
51
|
+
hash_key = @hash_key
|
52
|
+
hash_key = hash_key.join(@model.multi_column_join) if(hash_key.is_a?(Array))
|
53
|
+
|
54
|
+
query_hash = {:hash_value => hash_key}
|
55
|
+
|
56
|
+
query_hash = @range.reduce(query_hash) do |hsh, (key, val)|
|
57
|
+
if(!val.nil?)
|
58
|
+
hsh[RANGE_QUERY_MAP[key]] = @model.convert_to_dynamodb(@model.range_field.type, val)
|
59
|
+
end
|
60
|
+
hsh
|
61
|
+
end
|
62
|
+
@model.table.items.query(query_hash).map{|item| @model.item_to_instance(item)}
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
[:query, :where, :all, :each, :each_with_index].each do |method|
|
70
|
+
define_method(method) do |*args|
|
71
|
+
qc = QueryChain.new(self)
|
72
|
+
args = [] if !args
|
73
|
+
qc.send method, *args
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Dynameek
|
2
|
+
module Model
|
3
|
+
module Structure
|
4
|
+
|
5
|
+
@fields = {}
|
6
|
+
@hash_key = OpenStruct.new
|
7
|
+
@hash_key.field = nil
|
8
|
+
@hash_key.type = nil
|
9
|
+
|
10
|
+
@range = OpenStruct.new
|
11
|
+
@range.field = nil
|
12
|
+
@range.type = nil
|
13
|
+
|
14
|
+
@read_write = [10, 5]
|
15
|
+
|
16
|
+
@multi_column_hash_key_fields = []
|
17
|
+
@multi_column_join = "|"
|
18
|
+
|
19
|
+
|
20
|
+
def field fieldname, type
|
21
|
+
fieldname = fieldname.to_sym
|
22
|
+
type = type.to_sym
|
23
|
+
@fields[fieldname] = type
|
24
|
+
define_method(fieldname.to_s) { read_attribute(fieldname) }
|
25
|
+
define_method("#{fieldname.to_s}?") { !read_attribute(fieldname).nil? }
|
26
|
+
define_method("#{fieldname.to_s}=") {|value| write_attribute(fieldname, value) }
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
def hash_key fieldname
|
32
|
+
fieldname = fieldname.to_sym
|
33
|
+
check_field(fieldname)
|
34
|
+
@hash_key.field = fieldname
|
35
|
+
@hash_key.type = @fields[fieldname]
|
36
|
+
define_method(:hash_key) { read_attribute(fieldname) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def multi_column_join
|
40
|
+
@multi_column_join
|
41
|
+
end
|
42
|
+
def multi_column_join=(join)
|
43
|
+
@multi_column_join = join
|
44
|
+
end
|
45
|
+
def multi_column_hash_key?
|
46
|
+
!@multi_column_hash_key_fields.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
def multi_column_hash_key fieldnames
|
52
|
+
fields = fieldnames.map(&:to_sym)
|
53
|
+
fields.each{|f| check_field(f)}
|
54
|
+
@multi_column_hash_key_fields = fields
|
55
|
+
fieldname = fieldnames.map(&:to_s).join("_").to_s
|
56
|
+
@fields[fieldname] = :string
|
57
|
+
define_method(:hash_key) do
|
58
|
+
@multi_column_hash_key_fields.reduce([]) do |memo, field|
|
59
|
+
memo << attributes[field]
|
60
|
+
memo
|
61
|
+
end.join(@multi_column_join)
|
62
|
+
end
|
63
|
+
alias_method fieldname, :hash_key
|
64
|
+
@hash_key.field = fieldname
|
65
|
+
@hash_key.type = :string
|
66
|
+
end
|
67
|
+
|
68
|
+
def hash_key_field
|
69
|
+
@hash_key
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def range fieldname
|
74
|
+
fieldname = fieldname.to_sym
|
75
|
+
check_field(fieldname)
|
76
|
+
@range.field = fieldname
|
77
|
+
@range.type = @fields[fieldname]
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
def read_write read, write
|
82
|
+
@read_write = [read, write]
|
83
|
+
end
|
84
|
+
|
85
|
+
def read_units
|
86
|
+
@read_write[0]
|
87
|
+
end
|
88
|
+
def write_units
|
89
|
+
@read_write[1]
|
90
|
+
end
|
91
|
+
|
92
|
+
def fields
|
93
|
+
@fields
|
94
|
+
end
|
95
|
+
|
96
|
+
def range_field
|
97
|
+
@range.field.nil? ? nil : @range
|
98
|
+
end
|
99
|
+
|
100
|
+
def check_field(fieldname)
|
101
|
+
raise Exception("#{fieldname} is not a recognised field") if @fields[fieldname].nil?
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
data/lib/dynameek/model.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class Dynameek::Model
|
2
|
-
extend Dynameek::DynamoDb
|
3
|
-
extend Dynameek::
|
4
|
-
extend Dynameek::Query
|
2
|
+
extend Dynameek::Model::DynamoDb
|
3
|
+
extend Dynameek::Model::Structure
|
4
|
+
extend Dynameek::Model::Query
|
5
5
|
|
6
6
|
|
7
7
|
|
@@ -11,7 +11,7 @@ class Dynameek::Model
|
|
11
11
|
|
12
12
|
|
13
13
|
def self.find(hash_key, range_val=nil)
|
14
|
-
raise Exception("This has a composite hash with a range, the range val is required") if(range_val.nil? &&
|
14
|
+
raise Exception("This has a composite hash with a range, the range val is required") if(range_val.nil? && !range_field.field.nil?)
|
15
15
|
#multicolumn
|
16
16
|
hash_key = hash_key.join(multi_column_join) if(hash_key.is_a?(Array))
|
17
17
|
|
@@ -49,9 +49,12 @@ class Dynameek::Model
|
|
49
49
|
instance.save
|
50
50
|
end
|
51
51
|
|
52
|
-
|
52
|
+
def self.before_save_callbacks
|
53
|
+
@before_save_callbacks ||= Set.new
|
54
|
+
end
|
55
|
+
|
53
56
|
def self.before_save method
|
54
|
-
|
57
|
+
before_save_callbacks << method.to_sym
|
55
58
|
end
|
56
59
|
|
57
60
|
def save
|
@@ -63,7 +66,7 @@ class Dynameek::Model
|
|
63
66
|
memo[field] = val
|
64
67
|
memo
|
65
68
|
end
|
66
|
-
|
69
|
+
self.class.before_save_callbacks.each{|method| self.send method}
|
67
70
|
self.class.table.batch_write(
|
68
71
|
:put => [
|
69
72
|
attribs
|
data/lib/dynameek.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Dynameek
|
2
2
|
end
|
3
3
|
|
4
|
-
require File.join(File.dirname(__FILE__), *%w[dynameek dynamo_db])
|
5
|
-
require File.join(File.dirname(__FILE__), *%w[dynameek query])
|
6
|
-
require File.join(File.dirname(__FILE__), *%w[dynameek
|
4
|
+
require File.join(File.dirname(__FILE__), *%w[dynameek model dynamo_db])
|
5
|
+
require File.join(File.dirname(__FILE__), *%w[dynameek model query])
|
6
|
+
require File.join(File.dirname(__FILE__), *%w[dynameek model structure])
|
7
7
|
require File.join(File.dirname(__FILE__), *%w[dynameek model])
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: dynameek
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 5
|
5
|
-
version: 0.
|
5
|
+
version: 0.1.1a
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Max Dupenois
|
@@ -22,10 +22,10 @@ extensions: []
|
|
22
22
|
extra_rdoc_files: []
|
23
23
|
|
24
24
|
files:
|
25
|
-
- lib/dynameek/dynamo_db.rb
|
25
|
+
- lib/dynameek/model/dynamo_db.rb
|
26
|
+
- lib/dynameek/model/query.rb
|
27
|
+
- lib/dynameek/model/structure.rb
|
26
28
|
- lib/dynameek/model.rb
|
27
|
-
- lib/dynameek/model_structure.rb
|
28
|
-
- lib/dynameek/query.rb
|
29
29
|
- lib/dynameek.rb
|
30
30
|
homepage: http://github.com/maxdupenois/dynameek
|
31
31
|
licenses: []
|
data/lib/dynameek/dynamo_db.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
module Dynameek
|
2
|
-
module DynamoDb
|
3
|
-
def convert_from_dynamodb(type, value)
|
4
|
-
case type
|
5
|
-
when :integer
|
6
|
-
value.to_i
|
7
|
-
when :float
|
8
|
-
value.to_f
|
9
|
-
when :string
|
10
|
-
value.to_s
|
11
|
-
when :datetime
|
12
|
-
Time.at(value).to_datetime
|
13
|
-
else
|
14
|
-
value
|
15
|
-
end
|
16
|
-
end
|
17
|
-
def convert_to_dynamodb(type, value)
|
18
|
-
case type
|
19
|
-
when :datetime
|
20
|
-
value.to_time.to_f
|
21
|
-
else
|
22
|
-
value
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def exists?
|
27
|
-
table.exists?
|
28
|
-
end
|
29
|
-
|
30
|
-
def build!
|
31
|
-
return if dynamo_db.tables[table_name].exists?
|
32
|
-
new_table = dynamo_db.tables.create(table_name, @@read_write[0], @@read_write[1],
|
33
|
-
:hash_key => { @@hash_key.field => @@hash_key.type },
|
34
|
-
:range_key => { @@range.field => @@range.type == :datetime ? :number : @@range.type }
|
35
|
-
)
|
36
|
-
puts "Creating table, this may take a few minutes"
|
37
|
-
while new_table.status == :creating
|
38
|
-
sleep 1
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
@@table = nil
|
43
|
-
@@dynamo_db = nil
|
44
|
-
|
45
|
-
def dynamo_db
|
46
|
-
@@dynamo_db = AWS::DynamoDB.new if @@dynamo_db.nil?
|
47
|
-
@@dynamo_db
|
48
|
-
end
|
49
|
-
|
50
|
-
def table
|
51
|
-
build!
|
52
|
-
@@table = dynamo_db.tables[table_name] if @@table.nil?
|
53
|
-
@@table.load_schema if !@@table.schema_loaded?
|
54
|
-
@@table
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
@@ -1,106 +0,0 @@
|
|
1
|
-
module Dynameek
|
2
|
-
module ModelStructure
|
3
|
-
|
4
|
-
@@fields = {}
|
5
|
-
@@hash_key = OpenStruct.new
|
6
|
-
@@hash_key.field = nil
|
7
|
-
@@hash_key.type = nil
|
8
|
-
|
9
|
-
@@range = OpenStruct.new
|
10
|
-
@@range.field = nil
|
11
|
-
@@range.type = nil
|
12
|
-
|
13
|
-
@@read_write = [10, 5]
|
14
|
-
|
15
|
-
@@multi_column_hash_key_fields = []
|
16
|
-
@@multi_column_join = "|"
|
17
|
-
|
18
|
-
|
19
|
-
def field fieldname, type
|
20
|
-
fieldname = fieldname.to_sym
|
21
|
-
type = type.to_sym
|
22
|
-
@@fields[fieldname] = type
|
23
|
-
define_method(fieldname.to_s) { read_attribute(fieldname) }
|
24
|
-
define_method("#{fieldname.to_s}?") { !read_attribute(fieldname).nil? }
|
25
|
-
define_method("#{fieldname.to_s}=") {|value| write_attribute(fieldname, value) }
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def hash_key fieldname
|
31
|
-
fieldname = fieldname.to_sym
|
32
|
-
check_field(fieldname)
|
33
|
-
@@hash_key.field = fieldname
|
34
|
-
@@hash_key.type = @@fields[fieldname]
|
35
|
-
define_method(:hash_key) { read_attribute(fieldname) }
|
36
|
-
end
|
37
|
-
|
38
|
-
def multi_column_join
|
39
|
-
@@multi_column_join
|
40
|
-
end
|
41
|
-
def multi_column_join=(join)
|
42
|
-
@@multi_column_join = join
|
43
|
-
end
|
44
|
-
def multi_column_hash_key?
|
45
|
-
!@@multi_column_hash_key_fields.empty?
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
def multi_column_hash_key fieldnames
|
51
|
-
fields = fieldnames.map(&:to_sym)
|
52
|
-
fields.each{|f| check_field(f)}
|
53
|
-
@@multi_column_hash_key_fields = fields
|
54
|
-
fieldname = fieldnames.map(&:to_s).join("_").to_s
|
55
|
-
@@fields[fieldname] = :string
|
56
|
-
define_method(:hash_key) do
|
57
|
-
@@multi_column_hash_key_fields.reduce([]) do |memo, field|
|
58
|
-
memo << attributes[field]
|
59
|
-
memo
|
60
|
-
end.join(@@multi_column_join)
|
61
|
-
end
|
62
|
-
alias_method fieldname, :hash_key
|
63
|
-
@@hash_key.field = fieldname
|
64
|
-
@@hash_key.type = :string
|
65
|
-
end
|
66
|
-
|
67
|
-
def hash_key_field
|
68
|
-
@@hash_key
|
69
|
-
end
|
70
|
-
|
71
|
-
|
72
|
-
def range fieldname
|
73
|
-
fieldname = fieldname.to_sym
|
74
|
-
check_field(fieldname)
|
75
|
-
@@range.field = fieldname
|
76
|
-
@@range.type = @@fields[fieldname]
|
77
|
-
end
|
78
|
-
|
79
|
-
|
80
|
-
def read_write read, write
|
81
|
-
@@read_write = [read, write]
|
82
|
-
end
|
83
|
-
|
84
|
-
def read_units
|
85
|
-
@@read_write[0]
|
86
|
-
end
|
87
|
-
def write_units
|
88
|
-
@@read_write[1]
|
89
|
-
end
|
90
|
-
|
91
|
-
def fields
|
92
|
-
@@fields
|
93
|
-
end
|
94
|
-
|
95
|
-
def range_field
|
96
|
-
@@range.field.nil? ? nil : @@range
|
97
|
-
end
|
98
|
-
|
99
|
-
def check_field(fieldname)
|
100
|
-
raise Exception("#{fieldname} is not a recognised field") if @@fields[fieldname].nil?
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
|
data/lib/dynameek/query.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
module Dynameek
|
2
|
-
module Query
|
3
|
-
#Similar to dynamoids approach but lighter (hopefully)
|
4
|
-
|
5
|
-
class QueryChain
|
6
|
-
|
7
|
-
def initialize(model)
|
8
|
-
@model = model
|
9
|
-
@hash_key = nil
|
10
|
-
@range = {eq: nil, within: nil, gte: nil, gt: nil, lte: nil, lt: nil, begins_with: nil}
|
11
|
-
end
|
12
|
-
|
13
|
-
def query(hash_key)
|
14
|
-
@hash_key = hash_key
|
15
|
-
self
|
16
|
-
end
|
17
|
-
|
18
|
-
def where(value, op=:eq)
|
19
|
-
raise Exception("Op #{op.to_s} not recognised") if(!@range.keys.include?(op))
|
20
|
-
@range[op] = value
|
21
|
-
self
|
22
|
-
end
|
23
|
-
|
24
|
-
def all
|
25
|
-
run
|
26
|
-
end
|
27
|
-
|
28
|
-
def each
|
29
|
-
all.each
|
30
|
-
end
|
31
|
-
|
32
|
-
def each_with_index
|
33
|
-
all.each_with_index
|
34
|
-
end
|
35
|
-
|
36
|
-
RANGE_QUERY_MAP =
|
37
|
-
{
|
38
|
-
eq: :range_value,
|
39
|
-
within: :range_value,
|
40
|
-
gte: :range_gte,
|
41
|
-
gt: :range_greater_than,
|
42
|
-
lte: :range_lte,
|
43
|
-
lt: :range_less_than,
|
44
|
-
begins_with: :range_begins_with
|
45
|
-
}
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def run
|
50
|
-
hash_key = @hash_key
|
51
|
-
hash_key = hash_key.join(@model.multi_column_join) if(hash_key.is_a?(Array))
|
52
|
-
|
53
|
-
query_hash = {:hash_value => hash_key}
|
54
|
-
|
55
|
-
query_hash = @range.reduce(query_hash) do |hsh, (key, val)|
|
56
|
-
if(!val.nil?)
|
57
|
-
hsh[RANGE_QUERY_MAP[key]] = @model.convert_to_dynamodb(@model.range_field.type, val)
|
58
|
-
end
|
59
|
-
hsh
|
60
|
-
end
|
61
|
-
@model.table.items.query(query_hash).map{|item| @model.item_to_instance(item)}
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
[:query, :where, :all, :each, :each_with_index].each do |method|
|
69
|
-
define_method(method) do |*args|
|
70
|
-
qc = QueryChain.new(self)
|
71
|
-
args = [] if !args
|
72
|
-
qc.send method, *args
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
77
|
-
end
|