Class: Exwiw::MongodbCollectionConfig

Inherits:
Object
  • Object
show all
Includes:
Serdes
Defined in:
lib/exwiw/mongodb_collection_config.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from(obj) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/exwiw/mongodb_collection_config.rb', line 55

def self.from(obj)
  # Reject unknown keys before deserializing: Serdes silently drops them,
  # which would turn a typo'd key — or a key only the SQL adapters support,
  # like a field-level `raw_sql` — into a silent no-op (see
  # Exwiw::StrictKeys). `comment` is a declared attribute here and on the
  # nested belongs_to/field entries, so free-form notes stay accepted.
  if obj.is_a?(Hash)
    collection_name = obj["name"] || obj[:name]
    StrictKeys.validate!(self, obj, owner: "collection '#{collection_name}'")
  end

  instance = super
  instance.__send__(:validate_embedded!)
  instance.__send__(:validate_belongs_tos!)
  instance.__send__(:validate_fake_data!)
  instance
end

.from_symbol_keys(hash) ⇒ Object



73
74
75
# File 'lib/exwiw/mongodb_collection_config.rb', line 73

def self.from_symbol_keys(hash)
  from(JSON.parse(hash.to_json))
end

Instance Method Details

#embedded?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/exwiw/mongodb_collection_config.rb', line 77

def embedded?
  !embedded_in.nil?
end

#merge(passed) ⇒ Object

Merge an auto-generated config (passed) into this user-maintained one so that MongoidSchemaGenerator regenerations preserve hand-edited values.

  • structural facts come from the freshly generated config: primary_key, belongs_tos, embedded_in.
  • user customizations are kept from the receiver: filter, ignore, bulk_insert_chunk_size, query_timeout_ms, and each field's replace_with / replace_with_fake_data masking rule.
  • generated fields drive the field list (so added/removed fields track the model), but for a field the receiver already has, its masking decision wins outright — including the parts of it left unset.


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/exwiw/mongodb_collection_config.rb', line 101

def merge(passed)
  return passed if passed.to_hash == to_hash

  MongodbCollectionConfig.new.tap do |merged|
    merged.name = name
    merged.primary_key = passed.primary_key
    merged.filter = filter
    merged.bulk_insert_chunk_size = bulk_insert_chunk_size
    merged.query_timeout_ms = query_timeout_ms
    merged.ignore = ignore
    merged.ignore_type = ignore_type
    # A freshly generated comment (e.g. the skip_unsupported marker) wins so
    # it stays accurate; otherwise a hand-added note on a normal collection
    # is kept.
    merged.comment = passed.comment || comment
    merged.embedded_in = passed.embedded_in
    # User-owned, never regenerated: carry over from the existing config.
    merged.reverse_scope = reverse_scope

    # Structural facts of each belongs_to come from the freshly generated
    # config (including a generator-derived `references`), but the user-owned
    # `comment`/`ignore` — and a hand-edited `references`, which overrides the
    # generated one — carry over when the same relation still exists.
    receiver_belongs_to_by_identity = belongs_tos.each_with_object({}) { |bt, h| h[bt.identity] = bt }
    merged.belongs_tos = passed.belongs_tos.map do |pbt|
      receiver_bt = receiver_belongs_to_by_identity[pbt.identity]
      if receiver_bt
        pbt.comment = receiver_bt.comment if receiver_bt.comment
        pbt.ignore = receiver_bt.ignore unless receiver_bt.ignore.nil?
        pbt.ignore_type = receiver_bt.ignore_type if receiver_bt.ignore_type
        pbt.references = receiver_bt.references if receiver_bt.references
      end
      pbt
    end

    # Take each field from the freshly generated config (so structural facts
    # like `mongoid_field_name` track the model), but once the field already
    # exists in the receiver, EVERY masking-decision attribute comes from the
    # receiver — even when it is unset.
    #
    # "Even when unset" is the whole point: what these attributes record is a
    # human's decision about the field, and an absent value is a decision too
    # ("export this raw", "the flag is resolved"). Keeping the generated value
    # where the receiver has none was equivalent to "receiver wins" only while
    # the generator emitted no masks at all; under safe mode
    # (MongoidSchemaGenerator's `safe_new_columns`) it would put a default mask
    # back on a field somebody had deliberately unmasked, and silently mask it
    # again on every regeneration.
    receiver_field_by_name = fields.each_with_object({}) { |f, h| h[f.name] = f }
    merged.fields = passed.fields.map do |pf|
      receiver = receiver_field_by_name[pf.name]
      next pf unless receiver

      pf.replace_with = receiver.replace_with
      pf.replace_with_fake_data = receiver.replace_with_fake_data
      pf.comment = receiver.comment
      pf.ignore = receiver.ignore
      pf.needs_mask_decision = receiver.needs_mask_decision
      pf
    end
  end
end

#reject_ignored_members!Object

Drop the belongs_tos/fields flagged ignore:true so they are excluded from extraction. The config files on disk keep these entries; this is applied to the runtime config right after it is loaded (see Runner#load_table_config).



84
85
86
87
88
# File 'lib/exwiw/mongodb_collection_config.rb', line 84

def reject_ignored_members!
  self.belongs_tos = belongs_tos.reject(&:ignore)
  self.fields = fields.reject(&:ignore)
  self
end