public class ERXMigrationDatabase extends Object
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.
Modifier and Type | Class and Description |
---|---|
static class |
ERXMigrationDatabase.Migration
A convenience implementation of IERXMigration that passes in an
ERXMigrationDatabase instead of channel + model.
|
Modifier and Type | Method and Description |
---|---|
EOModel |
_blankModel()
Returns a blank EOModel with the connection dictionary from the adaptor.
|
static void |
_ensureNotEmpty(NSArray<EOSQLExpression> expressions,
String operationName,
boolean required)
Throws an ERXMigrationFailedException if the array of expressions is
empty.
|
static NSArray<String> |
_stringsForExpressions(NSArray<EOSQLExpression> expressions)
Returns an NSArray of SQL strings that correspond to the NSArray of
EOSQLExpressions that were passed in.
|
void |
_tableDropped(ERXMigrationTable table)
Notification callback to tell the database that the user dropped the
given table.
|
EOAdaptor |
adaptor()
Returns the adaptor for the given channel.
|
EOAdaptorChannel |
adaptorChannel()
Returns the adaptor channel.
|
static ERXMigrationDatabase |
database(EOAdaptorChannel adaptorChannel)
Returns an ERXMigrationDatabase for the given EOAdaptorChannel.
|
static ERXMigrationDatabase |
database(EOAdaptorChannel adaptorChannel,
EOModel model)
Returns an ERXMigrationDatabase for the given EOAdaptorChannel.
|
static ERXMigrationDatabase |
database(EOAdaptorChannel adaptorChannel,
EOModel model,
NSArray<String> languages)
Returns an ERXMigrationDatabase for the given EOAdaptorChannel.
|
ERXMigrationColumn |
existingColumnNamed(String tableName,
String columnName)
Shortcut to ERXMigrationTable.existingColumnNamed(String).
|
ERXMigrationTable |
existingTableNamed(String name)
Returns an ERXMigrationTable with the given table name.
|
boolean |
is(String name) |
NSArray<String> |
languages()
Returns the configured default languages for this migration.
|
EOModel |
model()
Returns the model associated with this migration.
|
ERXMigrationTable |
newTableNamed(String name)
Creates a new blank ERXMigrationTable.
|
String |
productName() |
EOSynchronizationFactory |
synchronizationFactory()
Returns the synchronization factory for this adaptor.
|
public EOSynchronizationFactory synchronizationFactory()
public EOAdaptor adaptor()
public EOModel model()
public NSArray<String> languages()
public EOAdaptorChannel adaptorChannel()
public ERXMigrationTable existingTableNamed(String name)
name
- the name of the table to lookuppublic ERXMigrationColumn existingColumnNamed(String tableName, String columnName)
tableName
- the name of the existing tablecolumnName
- the name of the existing columnpublic ERXMigrationTable newTableNamed(String name)
name
- the name of the table to createpublic EOModel _blankModel()
public void _tableDropped(ERXMigrationTable table)
table
- the table that was droppedpublic boolean is(String name)
name
- name of database to match productName()true
if productName().equals(name)productName()
public String productName()
ERXJDBCUtilities.databaseProductName(EOAdaptorChannel)
public static ERXMigrationDatabase database(EOAdaptorChannel adaptorChannel)
adaptorChannel
- the adaptor channel to operate withinpublic static ERXMigrationDatabase database(EOAdaptorChannel adaptorChannel, EOModel model, NSArray<String> languages)
adaptorChannel
- the adaptor channel to operate withinmodel
- the model that corresponds to this tablelanguages
- the languages to use for localizationpublic static ERXMigrationDatabase database(EOAdaptorChannel adaptorChannel, EOModel model)
adaptorChannel
- the adaptor channel to operate withinmodel
- the model that corresponds to this tablepublic static void _ensureNotEmpty(NSArray<EOSQLExpression> expressions, String operationName, boolean required)
expressions
- the expressions to checkoperationName
- the name of the operation being performed (for better error messages)required
- if true, an exception is thrown; if false, an error is loggedpublic static NSArray<String> _stringsForExpressions(NSArray<EOSQLExpression> expressions)
expressions
- the expressions to retrieve SQL forCopyright © 2002 – 2024 Project Wonder.