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
- .attribute(model, name) ⇒ Object
- .call(model) ⇒ Object
-
.dynamodb_type(field) ⇒ Object
Resolve a field's DynamoDB key type the way Dynamoid does.
- .gsi(model, index) ⇒ Object
- .lsi(model, index) ⇒ Object
-
.non_key_attributes(index) ⇒ Object
DynamoDB wants the projected attribute list only for INCLUDE projections.
Class Method Details
.attribute(model, name) ⇒ Object
28 29 30 31 32 33 |
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 28 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
13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 13 def call(model) # Required here rather than at load: {Schema.table_from} builds tables # from dumped data, and a CDK app doing only that has no reason to # carry Dynamoid. Anyone introspecting a model already has it loaded — # the model IS a Dynamoid class. require "dynamoid" 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.
39 40 41 42 43 |
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 39 def dynamodb_type(field) Dynamoid::PrimaryKeyTypeMapping.dynamodb_type(field[:type], field) rescue Dynamoid::Errors::UnsupportedKeyType field[:type] end |
.gsi(model, index) ⇒ Object
45 46 47 48 49 50 51 52 53 |
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 45 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
55 56 57 58 59 60 61 62 63 |
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 55 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.
66 67 68 69 70 |
# File 'lib/dynamoid/cdk/schema/introspector.rb', line 66 def non_key_attributes(index) return nil unless index.projection_type == :include Array(index.projected_attributes).map(&:to_s) end |