ERXMigrationDatabase Class Reference

Collaboration diagram for ERXMigrationDatabase:

Collaboration graph
[legend]

List of all members.

Classes

class  Migration

Public Member Functions

EOModel _blankModel ()
void _tableDropped (ERXMigrationTable table)
EOAdaptor adaptor ()
EOAdaptorChannel adaptorChannel ()
ERXMigrationColumn existingColumnNamed (String tableName, String columnName)
ERXMigrationTable existingTableNamed (String name)
boolean is (String name)
NSArray< Stringlanguages ()
EOModel model ()
ERXMigrationTable newTableNamed (String name)
String productName ()
EOSynchronizationFactory synchronizationFactory ()

Static Public Member Functions

static void _ensureNotEmpty (NSArray< EOSQLExpression > expressions, String operationName, boolean required)
static NSArray< String_stringsForExpressions (NSArray< EOSQLExpression > expressions)
static ERXMigrationDatabase database (EOAdaptorChannel adaptorChannel, EOModel model)
static ERXMigrationDatabase database (EOAdaptorChannel adaptorChannel, EOModel model, NSArray< String > languages)
static ERXMigrationDatabase database (EOAdaptorChannel adaptorChannel)

Static Public Attributes

static final Logger log = Logger.getLogger(ERXMigrationDatabase.class)

Private Member Functions

 ERXMigrationDatabase (EOAdaptorChannel adaptorChannel, EOModel model, NSArray< String > languages)
 ERXMigrationDatabase (EOAdaptorChannel adaptorChannel, EOModel model)

Private Attributes

EOAdaptorChannel _adaptorChannel
NSArray< String_languages
EOModel _model
NSMutableArray< ERXMigrationTable_tables


Detailed Description

ERXMigrationDatabase, ERXMigrationTable, and ERXMigrationColumn exist to make navigating the wonderous API of EOSynchronizationFactory not totally suck. Additionally, these simple models provide a way to insulate yourself from a dependency on EOModels during migrations while still taking advantage of the database independence of the SQL generation that EOF provides. The concept is inspired by the original migration by the Rails migrations API. Currently this API is only suitable for SQL migrations, which is why the terminology is based on the relational model vs EOF's more generic concepts like Models, Entities, and Attributes.

Prior to this API, and still fully supported (and required for more complicated operations), all migrations had to be written with SQL. The downside of writing SQL is that you are writing database-specific operations, which you must provide per-database implementations of. EOF already supports an API for database-agnostic SQL generation that via the EOSynchronizationFactory family of interfaces, but that API is overly complicated. ERXMigrationDatabase aims to provide a much simpler API on top of EOSynchronizationFactory that lets you perform common database-agnostic operations like adding and deleting columns, creating and dropping tables, adding primary keys, and adding foreign keys.

ERXMigrationDatabase is conceptually similar to an EOModel, ERXMigrationTable to an EOEntity, and ERXMigrationColumn to an EOAttribute. The names were specifically chosen to make the SQL-specific nature of the API clear (currently most of the API does not expose SQL-ness, but I'm assuming that in the future it may as the complexity of the operations provided increases). All of the API allows you to build an in-memory model of your structural changes along with some "perform now" method calls that actual execute SQL commands against the provided adaptor channel.

Let's take a look at some examples. Take the very common case of a migration that just adds a new column to a table: ERXMigrationDatabase.database(channel).existingTableNamed("Request").newStringColumn("requestedByEmailAddress", 255, true);

Another more complex case is that you are introducing an entirely new table that has a foreign key to some existing table:

 ERXMigrationDatabase database = ERXMigrationDatabase.database(channel);
 ERXMigrationTable table = ERXMigrationDatabase.database(channel).newTableNamed("TestPerson");
 table.newStringColumn("FirstName", 100, false);
 table.newStringColumn("LastName", 100, false);
 table.newStringColumn("EmailAddress", 100, false);
 table.newStringColumn("PhoneNumber", 10, true);
 table.newIntegerColumn("PantSize", true);
 table.newTimestampColumn("Birthdate", true);
 table.newBigDecimalColumn("HourlyRate", 32, 4, true);
 table.newFloatColumn("Rating", 10, 2, true);
 table.newBooleanColumn("Married", false);
 table.newIntBooleanColumn("Bald", false);
 table.newIntegerColumn("CompanyID", false);
 table.create();
 table.addForeignKey(table.existingColumnNamed("CompanyID"), database.existingTableNamed("Company").existingColumnNamed("companyID"));
 

In the above examples, database.existingTableNamed and table.existingColumnNamed are called. Calling table/database.existingXxx() does not perform database reverse engineering. It only creates a stub entry that is enough to perform operations like deleting, renaming, foreign keys, etc. Calling table.newXxx does not create the element in the database if the table is new, rather it returns a metadata wrapper (similar to EOAttribute, etc, but with migration-specific API's). However, if the table already exists, calling .newXxxColumn on the table will create the column immediately. You should generally not call .create() on an object you obtained from a call to .existingXxx, because it will only be a stub and generally insufficient to actually create in the database. The call to .existingXxx implies that the corresponding element already exists in the database. If you are creating an entire table, you can use the batching API like the second example where you can call database.newTableNamed(), then .newColumn all the columns in it, followed by a table.create() to create the entire block. For foreign keys, you must have .create()'d both tables (or use existing tables) prior to calling the foreign key methods.

It's important to note that this API relies entirely on EOSynchronizationFactory. If the sync factory for your plugin is wrong, the SQL generation in the ERXMigrationDatabase API's will likewise be wrong.

Author:
mschrag

Constructor & Destructor Documentation

ERXMigrationDatabase ( EOAdaptorChannel  adaptorChannel,
EOModel  model 
) [private]

Constructs an ERXMigrationDatabase

Parameters:
adaptorChannel the adaptor channel to connect to
model the model being migrated (necessary for more reliable sql generation)

ERXMigrationDatabase ( EOAdaptorChannel  adaptorChannel,
EOModel  model,
NSArray< String languages 
) [private]

Constructs an ERXMigrationDatabase

Parameters:
adaptorChannel the adaptor channel to connect to
model the model being migrated (necessary for more reliable sql generation)
languages the langauges to use for localization


Member Function Documentation

EOModel _blankModel (  ) 

Returns a blank EOModel with the connection dictionary from the adaptor.

Returns:
a blank EOModel

static void _ensureNotEmpty ( NSArray< EOSQLExpression >  expressions,
String  operationName,
boolean  required 
) [static]

Throws an ERXMigrationFailedException if the array of expressions is empty. Not all sync factories support all the listed operations, so this makes sure that the requested operation doesn't silently fail.

Parameters:
expressions the expressions to check
operationName the name of the operation being performed (for better error messages)
required if true, an exception is thrown; if false, an error is logged

static NSArray<String> _stringsForExpressions ( NSArray< EOSQLExpression >  expressions  )  [static]

Returns an NSArray of SQL strings that correspond to the NSArray of EOSQLExpressions that were passed in.

Parameters:
expressions the expressions to retrieve SQL for
Returns:
an NSArray of SQL strings

void _tableDropped ( ERXMigrationTable  table  ) 

Notification callback to tell the database that the user dropped the given table.

Parameters:
table the table that was dropped

EOAdaptor adaptor (  ) 

Returns the adaptor for the given channel.

Returns:
the adaptor for the given channel

EOAdaptorChannel adaptorChannel (  ) 

Returns the adaptor channel.

Returns:
the adaptor channel

static ERXMigrationDatabase database ( EOAdaptorChannel  adaptorChannel,
EOModel  model 
) [static]

Returns an ERXMigrationDatabase for the given EOAdaptorChannel. This will return a new ERXMigrationDatabase for every call, so if you need to perform multiple operations within a single database instance (for instance, adding foreign keys that talk to two tables), you should operate within a single ERXMigrationDatabase instance.

Parameters:
adaptorChannel the adaptor channel to operate within
model the model that corresponds to this table
Returns:
an ERXMigrationDatabase

static ERXMigrationDatabase database ( EOAdaptorChannel  adaptorChannel,
EOModel  model,
NSArray< String languages 
) [static]

Returns an ERXMigrationDatabase for the given EOAdaptorChannel. This will return a new ERXMigrationDatabase for every call, so if you need to perform multiple operations within a single database instance (for instance, adding foreign keys that talk to two tables), you should operate within a single ERXMigrationDatabase instance.

Parameters:
adaptorChannel the adaptor channel to operate within
model the model that corresponds to this table
languages the langauges to use for localization
Returns:
an ERXMigrationDatabase

static ERXMigrationDatabase database ( EOAdaptorChannel  adaptorChannel  )  [static]

Returns an ERXMigrationDatabase for the given EOAdaptorChannel. This will return a new ERXMigrationDatabase for every call, so if you need to perform multiple operations within a single database instance (for instance, adding foreign keys that talk to two tables), you should operate within a single ERXMigrationDatabase instance. If you have a model, you should use database(adaptorChannel, model) instead of this variant so that migrations can use the connection dictionary that is closest to being correct.

Parameters:
adaptorChannel the adaptor channel to operate within
Returns:
an ERXMigrationDatabase

ERXMigrationColumn existingColumnNamed ( String  tableName,
String  columnName 
)

Shortcut to ERXMigrationTable.existingColumnNamed(String).

Parameters:
tableName the name of the existing table
columnName the name of the existing column
Returns:
the ERXMigrationColumn

ERXMigrationTable existingTableNamed ( String  name  ) 

Returns an ERXMigrationTable with the given table name. This method does not perform any database reverse engineering. If you ask for an existing table, it will only return a stub of the table that should be sufficient for performing column operations and miscellaneous table operations like dropping. If you call newTableNamed, existingTableNamed will return the tables you create.

Parameters:
name the name of the table to lookup
Returns:
an ERXMigrationTable instance

boolean is ( String  name  ) 

See also:
productName()
Parameters:
name name of database to match productName()
Returns:
true if productName().equals(name)

NSArray<String> languages (  ) 

Returns the configured default languages for this migration.

Returns:
the configured default languages for this migration.

EOModel model (  ) 

Returns the model associated with this migration.

Returns:
the model associated with this migration

ERXMigrationTable newTableNamed ( String  name  ) 

Creates a new blank ERXMigrationTable. This is essentially the same as calling existingTableNamed except that it performs some simple validation to make sure this table hasn't been created in this ERXMigrationDatabase yet. Note that this check is not checking the actual database -- it is only verifying that you have not called newTableNamed or existingTableNamed on the name you provide. After calling newTableNamed, the instance returned from this method will also be returned from calls to existingTableNamed. The table will not be created from this call, only an object model is built.

Parameters:
name the name of the table to create
Returns:
a new ERXMigrationTable

String productName (  ) 

See also:
ERXJDBCUtilities.databaseProductName(EOAdaptorChannel)
Returns:
database product name

EOSynchronizationFactory synchronizationFactory (  ) 

Returns the synchronization factory for this adaptor.

Returns:
the synchronization factory for this adaptor


Member Data Documentation

EOAdaptorChannel _adaptorChannel [private]

NSArray<String> _languages [private]

EOModel _model [private]

final Logger log = Logger.getLogger(ERXMigrationDatabase.class) [static]


The documentation for this class was generated from the following file:

Generated on Sat May 26 06:43:16 2012 for Project Wonder by  doxygen 1.5.8