Module: Dynamoid::CDK::Schema::Introspector

Defined in:
lib/dynamoid/cdk/schema/introspector.rb

Overview

Reads a Dynamoid model class into a Descriptor: partition and sort keys, GSIs and LSIs, with DynamoDB attribute types resolved exactly the way Dynamoid resolves them for its own tables. Pure metadata — no DynamoDB connection and no AWS CDK.

Class Method Summary collapse

Class Method Details

.attribute(model, name) ⇒ Object

Raises:



24
25
26
27
28
29
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 24

def attribute(model, name)
  field = model.attributes[name.to_sym]
  raise Error, "#{model}: no field #{name.inspect} declared for a key attribute" if field.nil?

  Attribute.new(name: name.to_s, type: dynamodb_type(field))
end

.call(model) ⇒ Object



15
16
17
18
19
20
21
22
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 15

def call(model)
  Descriptor.new(
    partition_key: attribute(model, model.hash_key),
    sort_key: (attribute(model, model.range_key) if model.range_key),
    global_secondary_indexes: model.global_secondary_indexes.values.map { |i| gsi(model, i) },
    local_secondary_indexes: model.local_secondary_indexes.values.map { |i| lsi(model, i) }
  )
end

.dynamodb_type(field) ⇒ Object

Resolve a field's DynamoDB key type the way Dynamoid does. Its mapping doesn't emit :binary, but DynamoDB permits binary keys, so fall back to the field type on UnsupportedKeyType — mirroring Dynamoid's own index validation.



35
36
37
38
39
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 35

def dynamodb_type(field)
  Dynamoid::PrimaryKeyTypeMapping.dynamodb_type(field[:type], field)
rescue Dynamoid::Errors::UnsupportedKeyType
  field[:type]
end

.gsi(model, index) ⇒ Object



41
42
43
44
45
46
47
48
49
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 41

def gsi(model, index)
  Index.new(
    name: index.name,
    partition_key: attribute(model, index.hash_key),
    sort_key: (attribute(model, index.range_key) if index.range_key),
    projection_type: index.projection_type,
    non_key_attributes: non_key_attributes(index)
  )
end

.lsi(model, index) ⇒ Object



51
52
53
54
55
56
57
58
59
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 51

def lsi(model, index)
  Index.new(
    name: index.name,
    partition_key: nil, # an LSI shares the table's partition key
    sort_key: attribute(model, index.range_key),
    projection_type: index.projection_type,
    non_key_attributes: non_key_attributes(index)
  )
end

.non_key_attributes(index) ⇒ Object

DynamoDB wants the projected attribute list only for INCLUDE projections.



62
63
64
65
66
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 62

def non_key_attributes(index)
  return nil unless index.projection_type == :include

  Array(index.projected_attributes).map(&:to_s)
end