DbMigrationPlan - do-/node-doix-db GitHub Wiki

DbMigrationPlan is an object implementing basic functionality for building a sequence of SQL statements necessary to make the database structure and content comply with a given DbModel requirements.

Constructor

Not to be called directly. Use createMigrationPlan instead.

Properties

Name Type Description
db DbClient The database connection this migration plan is bound to
lang DbLang The SQL generator. Copy of db.lang
model DbModel The related database model instance. Copy of db.model
toBe Map {string => DbObject} The required database state. Merged from db.model.schemata.*.map
asIs Map {string => DbObject} The known existing database state.
toDo Map {string => [DbObject]} The roster of required modifications.

Events

Name Description Default handler
existing Emitted by loadExistingObjects method for each discovered database object which name is present in toBe map Add it to asIs map
unknown Emitted by loadExistingObjects method for each discovered database object not in toBe map None (reserved for application housekeeping)
recreate Emitted by inspectStructure method for each non-discoverable toBe value Add it to toDo.get ('recreate') array
create Emitted by inspectStructure method for each discoverable toBe value which name is absent from asIs map Add it to toDo.get ('create') and toDo.get ('comment') arrays
alter Emitted by inspectStructure method for each toBe value that requires (only) some ALTER ... statements Add it to toDo.get ('alter') array
comment Emitted by inspectStructure method for each toBe value that already exists, but requires the comment to be changed Add it to toDo.get ('comment') array
migrate Emitted by inspectStructure method for each toBe value that requires a complex data migration script Add it to toDo.get ('migrate') array
add-column Emitted by inspectStructure method for each DbColumn in toBe entities without an asIs counterpart Add it to asIs.get (tableName).toDo.get ('add-column') and asIs.get (tableName).toDo.get ('comment-column') arrays
alter-column Emitted by inspectStructure method for each DbColumn in toBe requiring some ALTER ... COLUMN ... Add it to asIs.get (tableName).toDo.get ('alter-column') array
migrate-column Emitted by inspectStructure method for each DbColumn in toBe requiring some complex data migration script Add it to asIs.get (tableName).toDo.get ('migrate-column') and asIs.get (tableName).toDo.get ('comment-column') arrays

Methods

genDDL ()

This generator yields a sequence of [sql, params] arrays to render the underlying database structure up to date with toBe. Actually, this is a shortcut to lang.genDDL () that must implement it for each of DBMS supported.

inspectStructure ()

For each toBe entry, emits:

  • 'recreate' and 'comment' (including a 'comment' for each of columns, if any) when the object type doesn't belong to lang.getDbObjectClassesToDiscover (i. e., it's a DbView);
  • 'create' and 'comment' when the object name misses from asIs;
  • whatever DbLang.getRequiredMutation () returns in the context of the eponymous asIs entry:
    • 'alter' if ALTER ... statements are to be generated for the object as a whole;
    • 'migrate' if data migration with temporary copy is required;
    • 'alter-column' if ALTER ... statements are to be generated for individual columns;
    • 'migrate-column' and 'comment' for columns to be recreated with a temporary copy;
    • nothing at all for an existing object already compatible with toBe requirements.

For equally typed DbRelation compatible toBe / asIs object pair, .columns are compared to emit add-column / alter-column / migrate-column events. Default handlers for those events fill up the asIs.get (tableName).toDo map, so the existing objects descriptions fetched from the physical database are completed with lists of necessary actions.

loadStructure ()

This asynchronous method fills up the asIs map with descriptions of the objects that may require some modification with ALTER statements or like, specifically:

  • mentioned in toBe,
  • found in the db database and
  • typed accordingly to lang.getDbObjectClassesToDiscover (so, by default, this method is synonymous to loadExistingObjects (DbTable)).

In general, data tables are considered the only common "hard" object type that worth discovering, comparing, altering etc. as "soft" objects (SQL views, stored procedures and so on) are much cheaper to drop and [re]create than to track for changes. Nevertheless, some DBMS might support some specific "hard" object types not representable with DbTable, for which case it takes to override lang.getDbObjectClassesToDiscover and implement the corresponding db.getStreamOfExisting....

loadExistingObjects (class)

For a given DbObject subclass DbThing, this asynchronous method invokes the db.getStreamOfExisting${Thing}s method and scans through the obtained stream emitting either 'existing' or 'unknown' events. The default 'existing' handler adds the object to asIs map, so by the end of execution asIs must contain descriptions of all objects of the mentioned class required by toBe and actually present in the database.