Class: Dynomite::Migration::Dsl

Inherits:
Object
  • Object
show all
Includes:
DbConfig, Common
Defined in:
lib/dynomite/migration/common.rb,
lib/dynomite/migration/dsl.rb,
lib/dynomite/migration/dsl/base_secondary_index.rb,
lib/dynomite/migration/dsl/local_secondary_index.rb,
lib/dynomite/migration/dsl/global_secondary_index.rb

Overview

Base class for LocalSecondaryIndex and GlobalSecondaryIndex

Defined Under Namespace

Modules: Common Classes: BaseSecondaryIndex, GlobalSecondaryIndex, LocalSecondaryIndex

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Common

#adjust_schema_and_attributes, #partition_key, #provisioned_throughput, #sort_key

Methods included from DbConfig

#db, included, #namespaced_table_name

Constructor Details

#initialize(method_name, table_name, &block) ⇒ Dsl

Returns a new instance of Dsl.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/dynomite/migration/dsl.rb', line 13

def initialize(method_name, table_name, &block)
  @method_name = method_name
  @table_name = table_name
  @block = block

  # Dsl fills in atttributes in as methods are called within the block.
  # Attributes for both create_table and updated_table:
  @attribute_definitions = []
  @provisioned_throughput = {
    read_capacity_units: 5,
    write_capacity_units: 5
  }

  # Attributes for create_table only:
  @key_schema = []

  # Attributes for update_table only:
  @gsi_indexes = []
  @lsi_indexes = []
end

Instance Attribute Details

#attribute_definitionsObject

Returns the value of attribute attribute_definitions.



11
12
13
# File 'lib/dynomite/migration/dsl.rb', line 11

def attribute_definitions
  @attribute_definitions
end

#key_schemaObject

Returns the value of attribute key_schema.



11
12
13
# File 'lib/dynomite/migration/dsl.rb', line 11

def key_schema
  @key_schema
end

#table_nameObject

Returns the value of attribute table_name.



12
13
14
# File 'lib/dynomite/migration/dsl.rb', line 12

def table_name
  @table_name
end

Instance Method Details

#evaluateObject



55
56
57
58
59
# File 'lib/dynomite/migration/dsl.rb', line 55

def evaluate
  return if @evaluated
  @block.call(self) if @block
  @evaluated = true
end

#global_secondary_index_updatesObject

maps each gsi to the hash structure expected by dynamodb update_table under the global_secondary_index_updates key:

{ create: {...} }
{ update: {...} }
{ delete: {...} }


178
179
180
181
182
# File 'lib/dynomite/migration/dsl.rb', line 178

def global_secondary_index_updates
  @gsi_indexes.map do |gsi|
    { gsi.action => gsi.params }
  end
end

#gsi(action = :create, index_name = nil, &block) ⇒ Object Also known as: global_secondary_index

t.gsi(:create) do |i|

i.partition_key = "category:string"
i.sort_key = "created_at:string" # optional

end



38
39
40
41
# File 'lib/dynomite/migration/dsl.rb', line 38

def gsi(action=:create, index_name=nil, &block)
  gsi_index = GlobalSecondaryIndex.new(action, index_name, &block)
  @gsi_indexes << gsi_index # store @gsi_index for the parent Dsl to use
end

#gsi_attribute_definitionsObject

>> resp = Post.db.describe_table(table_name: “demo-dev-posts”) >> resp.table.attribute_definitions.map(&:to_h)

> [:attribute_type=>“S”]



187
188
189
190
191
192
# File 'lib/dynomite/migration/dsl.rb', line 187

def gsi_attribute_definitions
  return @gsi_attribute_definitions if @gsi_attribute_definitions

  resp = db.describe_table(table_name: namespaced_table_name)
  @gsi_attribute_definitions = resp.table.attribute_definitions.map(&:to_h)
end

#gsi_secondary_index_createsObject

maps each lsi to the hash structure expected by dynamodb update_table under the global_secondary_index_updates key:

{ create: {...} }
{ update: {...} }
{ delete: {...} }


144
145
146
147
148
# File 'lib/dynomite/migration/dsl.rb', line 144

def gsi_secondary_index_creates
  @gsi_indexes.map do |gsi|
    gsi.params
  end
end

#lsi(action = :create, index_name = nil, &block) ⇒ Object Also known as: local_secondary_index

t.lsi(:create) do |i|

i.partition_key = "category:string"
i.sort_key = "created_at:string" # optional

end



48
49
50
51
52
# File 'lib/dynomite/migration/dsl.rb', line 48

def lsi(action=:create, index_name=nil, &block)
  # dont need action create but have it to keep the lsi and gsi method consistent
  lsi_index = LocalSecondaryIndex.new(index_name, &block)
  @lsi_indexes << lsi_index # store @lsi_index for the parent Dsl to use
end

#lsi_secondary_index_createsObject

maps each lsi to the hash structure expected by dynamodb update_table under the global_secondary_index_updates key:

{ create: {...} }
{ update: {...} }
{ delete: {...} }


132
133
134
135
136
# File 'lib/dynomite/migration/dsl.rb', line 132

def lsi_secondary_index_creates
  @lsi_indexes.map do |lsi|
    lsi.params
  end
end

#merge_gsi_attribute_definitions!Object

Goes thorugh all the gsi_indexes that have been built up in memory. Find the gsi object that creates an index and then grab the attribute_definitions from it.



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/dynomite/migration/dsl.rb', line 153

def merge_gsi_attribute_definitions!
  gsi_attrs = []

  gsi = @gsi_indexes.find { |i| i.action == :create }
  if gsi
    gsi.evaluate # force early evaluate since we need the params to
      # add: gsi_attribute_definitions + gsi_attrs
    gsi_attrs = gsi.attribute_definitions
  end

  # Merge existing attributes for update table
  all_gsi_attrs = @method_name == :update_table ?
    gsi_attribute_definitions + gsi_attrs :
    gsi_attrs

  all_attrs = (@attribute_definitions + all_gsi_attrs).uniq
  @attribute_definitions = all_attrs
end

#merge_lsi_attribute_definitions!Object

Goes thorugh all the lsi_indexes that have been built up in memory. Find the lsi object that creates an index and then grab the attribute_definitions from it.



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/dynomite/migration/dsl.rb', line 111

def merge_lsi_attribute_definitions!
  lsi = @lsi_indexes.first # DynamoDB only supports adding one index at a time anyway. The reason @lsi_indexes is an Array is because we're sharing the same class code for LSI and GSI
  if lsi
    lsi.evaluate # force early evaluate since we need the params to
      # add: gsi_attribute_definitions + lsi_attrs
    lsi_attrs = lsi.attribute_definitions
  end
  all_attrs = if lsi_attrs
                @attribute_definitions + lsi_attrs
              else
                @attribute_definitions
              end
  @attribute_definitions = all_attrs.uniq
end

#paramsObject

executor



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/dynomite/migration/dsl.rb', line 64

def params
  evaluate # lazy evaluation: wait until as long as possible before evaluating code block

  # Not using send because think its clearer in this case
  case @method_name
  when :create_table
    params_create_table
  when :update_table
    params_update_table
  end
end

#params_create_tableObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/dynomite/migration/dsl.rb', line 76

def params_create_table
  merge_lsi_attribute_definitions!
  merge_gsi_attribute_definitions!

  params = {
    table_name: namespaced_table_name,
    key_schema: @key_schema,
    attribute_definitions: @attribute_definitions,
    provisioned_throughput: @provisioned_throughput
  }

  params[:local_secondary_indexes] = lsi_secondary_index_creates unless @lsi_indexes.empty?
  params[:global_secondary_indexes] = gsi_secondary_index_creates unless @gsi_indexes.empty?
  params
end

#params_update_tableObject



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/dynomite/migration/dsl.rb', line 92

def params_update_table
  merge_gsi_attribute_definitions!

  params = {
    table_name: namespaced_table_name,
    attribute_definitions: @attribute_definitions,
    # update table take values only some values for the "parent" table
    # no key_schema, update_table does not handle key_schema for the "parent" table
  }
  # only set "parent" table provisioned_throughput if user actually invoked
  # it in the dsl
  params[:provisioned_throughput] =  @provisioned_throughput if @provisioned_throughput_set_called
  params[:global_secondary_index_updates] = global_secondary_index_updates
  params
end