Class: Exwiw::DbSchemaGenerator
- Inherits:
-
Object
- Object
- Exwiw::DbSchemaGenerator
- Defined in:
- lib/exwiw/db_schema_generator.rb
Overview
Generates (and tidies) a schema config from a live database connection instead of from an application's models — see DbIntrospector for why an application exwiw cannot load needs this.
It mirrors SchemaGenerator table for table and column for column, with one deliberate difference in how belongs_tos are reconciled (see #merged_belongs_tos) and one structural simplification: the output directory is flat, because a connection addresses exactly one database. A second database is a second run against a second connection, which is also how the extraction itself treats it.
Defined Under Namespace
Classes: TidyResult
Instance Method Summary collapse
-
#generate! ⇒ Object
Write one config file per table in the database, merged with whatever is already on disk, and return the configs as written.
-
#initialize(introspector:, output_dir:, safe_new_columns: true) ⇒ DbSchemaGenerator
constructor
safe_new_columnsmatches SchemaGenerator's: on (the default) every column is emitted masked as far as its type allows and flaggedneeds_mask_decision: true, and #merge lets an already-decided entry win, so in practice only genuinely new columns keep that treatment. -
#tidy! ⇒ Object
Reconcile the config files on disk against the database, removing only what no longer exists there:.
Constructor Details
#initialize(introspector:, output_dir:, safe_new_columns: true) ⇒ DbSchemaGenerator
safe_new_columns matches SchemaGenerator's: on (the default) every
column is emitted masked as far as its type allows and flagged
needs_mask_decision: true, and #merge lets an already-decided entry win,
so in practice only genuinely new columns keep that treatment.
44 45 46 47 48 |
# File 'lib/exwiw/db_schema_generator.rb', line 44 def initialize(introspector:, output_dir:, safe_new_columns: true) @introspector = introspector @output_dir = output_dir @safe_new_columns = safe_new_columns end |
Instance Method Details
#generate! ⇒ Object
Write one config file per table in the database, merged with whatever is already on disk, and return the configs as written.
Unlike SchemaGenerator, the configs are built inside the write path rather than by a separate builder: what the generated belongs_tos are — and therefore which columns count as structural and must not be masked — depends on the existing file (see #merged_belongs_tos), so the two cannot be separated without introspecting the disk twice.
58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/exwiw/db_schema_generator.rb', line 58 def generate! FileUtils.mkdir_p(@output_dir) @introspector.table_names.map do |table_name| path = File.join(@output_dir, "#{table_name}.json") existing = read_config(path) generated = build_table(table_name, existing) config_to_write = existing ? existing.merge(generated) : generated File.write(path, JSON.pretty_generate(config_to_write.to_hash) + "\n") config_to_write end end |
#tidy! ⇒ Object
Reconcile the config files on disk against the database, removing only what no longer exists there:
- a config file whose table is gone is deleted,
- columns a surviving table no longer has are dropped, and
- a belongs_to pointing at a table that is gone is dropped.
The belongs_to case is this generator's own. Because #generate! only ever
adds relations (never rewrites the list), a relation whose target table
was dropped would otherwise survive every regeneration, and a belongs_to
with no target table crashes dependency resolution at extraction time.
An ignore: true entry is kept regardless: those are user tombstones
recording a decision ("this relation is deliberately not extracted"), and
deleting one would invite the next regeneration to add the edge back.
Like SchemaGenerator#tidy!, nothing is added or regenerated here: every
surviving entry keeps its hand-edited comment / ignore /
replace_with untouched. Returns a TidyResult describing the removals.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/exwiw/db_schema_generator.rb', line 90 def tidy! result = TidyResult.new return result unless Dir.exist?(@output_dir) # Views are not generated (see DbIntrospector::Base#table_names), so a # config naming one is stale by the same definition as a dropped table. existing_tables = @introspector.table_names.to_set Dir[File.join(@output_dir, "*.json")].sort.each do |path| existing = TableConfig.from(JSON.parse(File.read(path))) unless existing_tables.include?(existing.name) File.delete(path) result.add_removed_table(existing.name) next end changed = false changed |= remove_stale_columns(existing, result) changed |= remove_dangling_belongs_tos(existing, existing_tables, result) File.write(path, JSON.pretty_generate(existing.to_hash) + "\n") if changed end result end |