Class: DynamodbModel::Migration::Dsl

Inherits:
Object
  • Object
show all
Includes:
DbConfig, Common
Defined in:
lib/dynamodb_model/migration/common.rb,
lib/dynamodb_model/migration/dsl.rb,
lib/dynamodb_model/migration/dsl/base_secondary_index.rb,
lib/dynamodb_model/migration/dsl/local_secondary_index.rb,
lib/dynamodb_model/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/dynamodb_model/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/dynamodb_model/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/dynamodb_model/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/dynamodb_model/migration/dsl.rb', line 12

def table_name
  @table_name
end

Instance Method Details

#evaluateObject



55
56
57
58
59
# File 'lib/dynamodb_model/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: {...} }


156
157
158
159
160
# File 'lib/dynamodb_model/migration/dsl.rb', line 156

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

#gsi(action, index_name = nil, &block) ⇒ Object Also known as: global_secondary_index, local_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/dynamodb_model/migration/dsl.rb', line 38

def gsi(action, 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”]



165
166
167
168
169
170
# File 'lib/dynamodb_model/migration/dsl.rb', line 165

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_create_attribute_definitionsObject

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.



135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/dynamodb_model/migration/dsl.rb', line 135

def gsi_create_attribute_definitions
  gsi = @gsi_indexes.find { |gsi| gsi.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
  all_attrs = if gsi_attrs
                gsi_attribute_definitions + gsi_attrs
              else
                gsi_attribute_definitions
              end
  all_attrs.uniq
end

#lsi(action = :create, index_name = nil, &block) ⇒ Object

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/dynamodb_model/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_create_attribute_definitionsObject

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.



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

def lsi_create_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
  all_attrs.uniq
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: {...} }


112
113
114
115
116
# File 'lib/dynamodb_model/migration/dsl.rb', line 112

def lsi_secondary_index_creates
  @lsi_indexes.map do |lsi|
    { lsi.action => lsi.params }
  end
end

#paramsObject

executor



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/dynamodb_model/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
# File 'lib/dynamodb_model/migration/dsl.rb', line 76

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

  params[:local_secondary_index_creates] = local_secondary_index_creates unless @lsi_indexes.empty?
  params
end

#params_update_tableObject



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/dynamodb_model/migration/dsl.rb', line 118

def params_update_table
  params = {
    table_name: namespaced_table_name,
    attribute_definitions: gsi_create_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