package er.extensions.migration;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.sql.Types;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webobjects.eoaccess.EOAttribute;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.eoaccess.EOJoin;
import com.webobjects.eoaccess.EOModel;
import com.webobjects.eoaccess.EORelationship;
import com.webobjects.eoaccess.EOSQLExpression;
import com.webobjects.eoaccess.EOSchemaGeneration;
import com.webobjects.eoaccess.EOSchemaSynchronization;
import com.webobjects.eocontrol.EOKeyValueQualifier;
import com.webobjects.eocontrol.EOQualifier;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSData;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableArray;
import com.webobjects.foundation.NSTimestamp;
import er.extensions.jdbc.ERXJDBCUtilities;
import er.extensions.jdbc.ERXSQLHelper;
import er.extensions.jdbc.ERXSQLHelper.CustomTypes;
/**
* ERXMigrationTable provides table-level migration API's. To obtain a table, you
* should call ERXMigrationDatabase.existingTableNamed or ERXMigrationDatabase.newTableNamed.
* Note: The .newXxxColumn API's cannot reference prototypes for the same reason that migrations
* in general cannot reference EOModels.
*
* @author mschrag
*/
public class ERXMigrationTable {
private static final Logger log = LoggerFactory.getLogger(ERXMigrationDatabase.class);
private ERXMigrationDatabase _database;
private NSMutableArray<ERXMigrationColumn> _columns;
private NSMutableArray<ERXMigrationIndex> _indexes;
private NSMutableArray<ERXMigrationForeignKey> _foreignKeys;
private String _name;
private boolean _new;
/**
* Constructs an ERXMigrationTable.
*
* @param database the database this table is within
* @param name the name of this table
*/
protected ERXMigrationTable(ERXMigrationDatabase database, String name) {
_database = database;
_columns = new NSMutableArray<>();
_indexes = new NSMutableArray<>();
_foreignKeys = new NSMutableArray<>();
_name = name;
_new = true;
}
/**
* Returns the ERXMigrationDatabase parent of this table.
*
* @return the ERXMigrationDatabase parent of this table
*/
public ERXMigrationDatabase database() {
return _database;
}
/**
* Returns the configured default languages for this migration.
* @return the configured default languages for this migration
*/
public NSArray<String> languages() {
//TODO AK have a local override
return database().languages();
}
/**
* Sets the name of this table. This does not perform a table rename operation.
*
* @param name the name of this table
*/
public void _setName(String name) {
_name = name;
}
/**
* Returns the name of this table.
*
* @return the name of this table
*/
public String name() {
return _name;
}
/**
* Returns true if this table has not yet been created in the database.
*
* @return if this table has not yet been created in the database
*/
public boolean isNew() {
return _new;
}
/**
* Sets whether or not this table has been created in the database.
*
* @param isNew if true, the table has been created
*/
public void _setNew(boolean isNew) {
_new = isNew;
}
/**
* Returns an EOEntity representing this table with no
* EOAttributes in it.
*
* @return a shell of an EOEntity for this table
*/
public EOEntity _blankEntity() {
EOModel newModel = _database._blankModel();
EOEntity newEntity = new EOEntity();
newEntity.setExternalName(_name);
newEntity.setName("ERXMigrationTable_" + _name);
newModel.addEntity(newEntity);
return newEntity;
}
/**
* Returns an EOEntity representing this table that
* contains all of the EOAttributes for any
* ERXMigrationColumn that has been created or
* retrieved from this table.
*
* @return an EOAttributeful EOEntity for this table
*/
public EOEntity _newEntity() {
EOEntity entity = _blankEntity();
NSMutableArray<EOAttribute> primaryKeyAttributes = new NSMutableArray<>();
for (ERXMigrationColumn column : _columns) {
EOAttribute attribute = column._newAttribute(entity);
if (column.isPrimaryKey()) {
primaryKeyAttributes.addObject(attribute);
}
}
entity.setPrimaryKeyAttributes(primaryKeyAttributes);
return entity;
}
/**
* Returns the ERMigrationColumn for the column with the given name. If
* no column has already been created via a newColumn call, then this
* will simply return a shell ERXMigrationColumn that should be sufficient
* for performing drop, rename, and other reference operations.
*
* @param name the name of the column to retrieve
* @return the ERXMigrationColumn for the column name
*/
@SuppressWarnings("unchecked")
public ERXMigrationColumn existingColumnNamed(String name) {
NSArray<ERXMigrationColumn> existingColumns = EOQualifier.filteredArrayWithQualifier(_columns, new EOKeyValueQualifier("name", EOQualifier.QualifierOperatorCaseInsensitiveLike, name));
ERXMigrationColumn column;
if (existingColumns.count() == 0) {
if (_new) {
throw new IllegalStateException("You requested the column named '" + name + "' in the table '" + _name + "', but that column hasn't been created yet.");
}
try {
column = _newColumn(name, Types.OTHER, 0, 0, 0, false, null, null, false);
}
catch (SQLException e) {
throw new IllegalStateException("This should never have executed a database operation.", e);
}
column._setNew(false);
}
else {
column = existingColumns.objectAtIndex(0);
}
return column;
}
/**
* Returns a simple single-attribute-mapping EORelationship between two columns. This
* is called by the foreign key generator.
*
* @param sourceColumns the source attributes of the relationship
* @param destinationColumns the destination attributes of the relationship
* @return the EORelationship that joins the two given columns
*/
public EORelationship _newRelationship(ERXMigrationColumn[] sourceColumns, ERXMigrationColumn[] destinationColumns) {
NSMutableArray<EOAttribute> sourceAttributes = new NSMutableArray<>();
NSMutableArray<EOAttribute> destinationAttributes = new NSMutableArray<>();
if (sourceColumns.length != destinationColumns.length) {
throw new IllegalArgumentException("The number of source columns must match the number of destination columns.");
}
EOEntity sourceEntity = sourceColumns[0].table()._blankEntity();
EOEntity destinationEntity = destinationColumns[0].table()._blankEntity();
for (int columnNum = 0; columnNum < sourceColumns.length; columnNum ++) {
EOAttribute sourceAttribute = sourceColumns[columnNum]._newAttribute(sourceEntity);
sourceAttributes.addObject(sourceAttribute);
EOAttribute destinationAttribute = destinationColumns[columnNum]._newAttribute(destinationEntity);
destinationAttributes.addObject(destinationAttribute);
}
destinationEntity.setPrimaryKeyAttributes(destinationAttributes);
EORelationship relationship = new EORelationship();
relationship.setName(sourceAttributes.objectAtIndex(0).name() + "_" + destinationAttributes.objectAtIndex(0).name());
relationship.setEntity(sourceEntity);
for (int attributeNum = 0; attributeNum < sourceAttributes.count(); attributeNum ++) {
EOJoin join = new EOJoin(sourceAttributes.objectAtIndex(attributeNum), destinationAttributes.objectAtIndex(attributeNum));
relationship.addJoin(join);
}
return relationship;
}
/**
* Returns a new ERXMigrationColumn with the given attributes. This method is the
* most general-purpose of the .newXxx methods. Calling this method will not
* actually create the column, rather it will only return a metadata wrapper of
* the attributes you specify. Call .create() on the resulting column object
* to create the column (or create several columns and then call .create() on
* this table to create an entire table).
*
* @param name the name of the column to create
* @param jdbcType the JDBC type of the column (see java.sql.Types)
* @param width the width of the column (or 0 for unspecified)
* @param precision the precision of the column (or 0 for unspecified)
* @param scale the scale of the column (or 0 for unspecified)
* @param allowsNull if true, the column will allow null values
* @param overrideValueType value type associated with the underlying attribute (or <code>null</code> for autoselect)
* @param defaultValue the default value for the column
* @param autocreate if <code>true</code> will call create on new column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn _newColumn(String name, int jdbcType, int width, int precision, int scale, boolean allowsNull, String overrideValueType, Object defaultValue, boolean autocreate) throws SQLException {
ERXMigrationColumn newColumn = new ERXMigrationColumn(this, name, jdbcType, width, precision, scale, allowsNull, overrideValueType, defaultValue);
_columns.addObject(newColumn);
if (autocreate) {
newColumn.create();
}
return newColumn;
}
/**
* Returns a new ERXMigrationColumn with the given attributes. This method is the
* most general-purpose of the .newXxx methods. If this table already exists,
* calling the .newXxxColumn methods will immediate execute the SQL to add the
* columns to the table. If this table is new, however, calling .newXxxColumn
* will only return a metadata object, and you must call .create() on
* the table.
*
* @param name the name of the column to create
* @param jdbcType the JDBC type of the column (see java.sql.Types)
* @param width the width of the column (or 0 for unspecified)
* @param precision the precision of the column (or 0 for unspecified)
* @param scale the scale of the column (or 0 for unspecified)
* @param allowsNull if true, the column will allow null values
* @param overrideValueType value type associated with the underlying attribute (or <code>null</code> for autoselect)
* @param defaultValue the default value for the column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newColumn(String name, int jdbcType, int width, int precision, int scale, boolean allowsNull, String overrideValueType, Object defaultValue) throws SQLException {
return _newColumn(name, jdbcType, width, precision, scale, allowsNull, overrideValueType, defaultValue, !_new);
}
/**
* Returns a new ERXMigrationColumn with the given attributes. This method is the
* most general-purpose of the .newXxx methods. If this table already exists,
* calling the .newXxxColumn methods will immediate execute the SQL to add the
* columns to the table. If this table is new, however, calling .newXxxColumn
* will only return a metadata object, and you must call .create() on
* the table.
*
* @param name the name of the column to create
* @param jdbcType the JDBC type of the column (see java.sql.Types)
* @param width the width of the column (or 0 for unspecified)
* @param precision the precision of the column (or 0 for unspecified)
* @param scale the scale of the column (or 0 for unspecified)
* @param allowsNull if true, the column will allow null values
* @param overrideValueType value type associated with the underlying attribute (or <code>null</code> for autoselect)
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newColumn(String name, int jdbcType, int width, int precision, int scale, boolean allowsNull, String overrideValueType) throws SQLException {
return _newColumn(name, jdbcType, width, precision, scale, allowsNull, overrideValueType, null, !_new);
}
/**
* Returns a new String column (VARCHAR). See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param width the max width of the varchar
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newStringColumn(String name, int width, boolean allowsNull) throws SQLException {
return newColumn(name, Types.VARCHAR, width, 0, 0, allowsNull, null);
}
/**
* Returns a new String column (VARCHAR). See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param width the max width of the varchar
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newStringColumn(String name, int width, boolean allowsNull, String defaultValue) throws SQLException {
return newColumn(name, Types.VARCHAR, width, 0, 0, allowsNull, null, defaultValue);
}
/**
* Returns a new String column (VARCHAR) with an unbounded length. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newStringColumn(String name, boolean allowsNull) throws SQLException {
return newLargeStringColumn(name, allowsNull);
}
/**
* Returns a new String column (VARCHAR) that corresponds to the varcharLarge prototype. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newLargeStringColumn(String name, boolean allowsNull) throws SQLException {
ERXSQLHelper sqlHelper = ERXSQLHelper.newSQLHelper(_database.adaptorChannel());
return newColumn(name, sqlHelper.varcharLargeJDBCType(), sqlHelper.varcharLargeColumnWidth(), 0, 0, allowsNull, null);
}
/**
* Returns a new String column (VARCHAR) that corresponds to the varcharLarge prototype. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newStringColumn(String name, boolean allowsNull, String defaultValue) throws SQLException {
ERXSQLHelper sqlHelper = ERXSQLHelper.newSQLHelper(_database.adaptorChannel());
return newColumn(name, sqlHelper.varcharLargeJDBCType(), sqlHelper.varcharLargeColumnWidth(), 0, 0, allowsNull, null, defaultValue);
}
/**
* Returns a new localized String column (VARCHAR). See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param width the max width of the varchar
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public NSArray<ERXMigrationColumn> newLocalizedStringColumns(String name, int width, boolean allowsNull) throws SQLException {
NSMutableArray<ERXMigrationColumn> result = new NSMutableArray<>();
for (String language : languages()) {
ERXMigrationColumn column = newColumn(localizedColumnName(name, language), Types.VARCHAR, width, 0, 0, allowsNull, null);
result.addObject(column);
}
return result;
}
/**
* Returns a new localized String column (VARCHAR). See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param width the max width of the varchar
* @param allowsNull if true, the column will allow null values
* @param languages the languages [ex. ("en","ja","fr")]
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public NSArray<ERXMigrationColumn> newLocalizedStringColumns(String name, int width, boolean allowsNull, NSArray<String> languages) throws SQLException {
NSMutableArray<ERXMigrationColumn> result = new NSMutableArray<>();
for (String language : languages) {
ERXMigrationColumn column = newColumn(localizedColumnName(name, language), Types.VARCHAR, width, 0, 0, allowsNull, null);
result.addObject(column);
}
return result;
}
private String localizedColumnName(String name, String language) {
return name + "_" + language;
}
/**
* Returns a new localized String column (VARCHAR). See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param width the max width of the varchar
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public NSArray<ERXMigrationColumn> newLocalizedStringColumns(String name, int width, boolean allowsNull, String defaultValue) throws SQLException {
NSMutableArray<ERXMigrationColumn> result = new NSMutableArray<>();
for (String language : languages()) {
ERXMigrationColumn column = newColumn(localizedColumnName(name, language), Types.VARCHAR, width, 0, 0, allowsNull, null, defaultValue);
result.addObject(column);
}
return result;
}
/**
* Returns a new localized String column (VARCHAR). See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param width the max width of the varchar
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @param languages the languages [ex. ("en","ja","fr")]
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public NSArray<ERXMigrationColumn> newLocalizedStringColumns(String name, int width, boolean allowsNull, String defaultValue, NSArray<String> languages) throws SQLException {
NSMutableArray<ERXMigrationColumn> result = new NSMutableArray<>();
for (String language : languages) {
ERXMigrationColumn column = newColumn(localizedColumnName(name, language), Types.VARCHAR, width, 0, 0, allowsNull, null, defaultValue);
result.addObject(column);
}
return result;
}
/**
* Returns a new localized string blob column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public NSArray<ERXMigrationColumn> newLocalizedClobColumns(String name, boolean allowsNull) throws SQLException {
NSMutableArray<ERXMigrationColumn> result = new NSMutableArray<>();
for (String language : languages()) {
ERXMigrationColumn column = newColumn(localizedColumnName(name, language), Types.CLOB, 0, 0, 0, allowsNull, null);
result.addObject(column);
}
return result;
}
/**
* Returns a new localized string blob column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param languages the languages [ex. ("en","ja","fr")]
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public NSArray<ERXMigrationColumn> newLocalizedClobColumns(String name, boolean allowsNull, NSArray<String> languages) throws SQLException {
NSMutableArray<ERXMigrationColumn> result = new NSMutableArray<>();
for (String language : languages) {
ERXMigrationColumn column = newColumn(localizedColumnName(name, language), Types.CLOB, 0, 0, 0, allowsNull, null);
result.addObject(column);
}
return result;
}
/**
* Returns a new integer column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newIntegerColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.INTEGER, 0, 0, 0, allowsNull, null);
}
/**
* Returns a new integer column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newIntegerColumn(String name, boolean allowsNull, Integer defaultValue) throws SQLException {
return newColumn(name, Types.INTEGER, 0, 0, 0, allowsNull, null, defaultValue);
}
/**
* Returns a new integer column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param scale the scale of the integer
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newIntegerColumn(String name, int scale, boolean allowsNull) throws SQLException {
return newColumn(name, Types.INTEGER, 0, 0, scale, allowsNull, null);
}
/**
* Returns a new integer column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param scale the scale of the integer
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newIntegerColumn(String name, int scale, boolean allowsNull, Integer defaultValue) throws SQLException {
return newColumn(name, Types.INTEGER, 0, 0, scale, allowsNull, null, defaultValue);
}
/**
* Returns a new integer column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param scale the scale of the integer
* @param precision the precision of the integer
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newIntegerColumn(String name, int scale, int precision, boolean allowsNull) throws SQLException {
return newColumn(name, Types.INTEGER, 0, scale, precision, allowsNull, null);
}
/**
* Returns a new integer column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param scale the scale of the integer
* @param precision the precision of the integer
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newIntegerColumn(String name, int scale, int precision, boolean allowsNull, Object defaultValue) throws SQLException {
return newColumn(name, Types.INTEGER, 0, scale, precision, allowsNull, null, defaultValue);
}
/**
* Returns a new small integer column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newSmallIntegerColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.SMALLINT, 0, 0, 0, allowsNull, null);
}
/**
* Returns a new small integer column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newSmallIntegerColumn(String name, boolean allowsNull, Short defaultValue) throws SQLException {
return newColumn(name, Types.SMALLINT, 0, 0, 0, allowsNull, null, defaultValue);
}
/**
* Returns a new long column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newBigIntegerColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.BIGINT, 0, 0, 0, allowsNull, null);
}
/**
* Returns a new long column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newBigIntegerColumn(String name, boolean allowsNull, Long defaultValue) throws SQLException {
return newColumn(name, Types.BIGINT, 0, 0, 0, allowsNull, null, defaultValue);
}
/**
* Returns a new float column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param scale the scale of the float
* @param precision the precision of the float
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newFloatColumn(String name, int precision, int scale, boolean allowsNull) throws SQLException {
return newColumn(name, Types.FLOAT, 0, precision, scale, allowsNull, null);
}
/**
* Returns a new float column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param scale the scale of the float
* @param precision the precision of the float
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newFloatColumn(String name, int precision, int scale, boolean allowsNull, Float defaultValue) throws SQLException {
return newColumn(name, Types.FLOAT, 0, precision, scale, allowsNull, null, defaultValue);
}
/**
* Returns a new double column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param scale the scale of the double
* @param precision the precision of the double
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newDoubleColumn(String name, int precision, int scale, boolean allowsNull) throws SQLException {
return newColumn(name, Types.DOUBLE, 0, precision, scale, allowsNull, null);
}
/**
* Returns a new double column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param scale the scale of the double
* @param precision the precision of the double
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newDoubleColumn(String name, int precision, int scale, boolean allowsNull, Double defaultValue) throws SQLException {
return newColumn(name, Types.DOUBLE, 0, precision, scale, allowsNull, null, defaultValue);
}
/**
* Returns a new BigDecimal column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param scale the scale of the BigDecimal
* @param precision the precision of the BigDecimal
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newBigDecimalColumn(String name, int precision, int scale, boolean allowsNull) throws SQLException {
return newColumn(name, Types.DECIMAL, 0, precision, scale, allowsNull, null);
}
/**
* Returns a new BigDecimal column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param scale the scale of the BigDecimal
* @param precision the precision of the BigDecimal
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newBigDecimalColumn(String name, int precision, int scale, boolean allowsNull, BigDecimal defaultValue) throws SQLException {
return newColumn(name, Types.DECIMAL, 0, precision, scale, allowsNull, null, defaultValue);
}
/**
* Returns a new varchar(5) boolean column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newBooleanColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.VARCHAR, 5, 0, 0, allowsNull, null);
}
/**
* Returns a new varchar(5) boolean column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newBooleanColumn(String name, boolean allowsNull, Boolean defaultValue) throws SQLException {
return newColumn(name, Types.VARCHAR, 5, 0, 0, allowsNull, null, defaultValue == null ? null : defaultValue.toString());
}
/**
* Returns a new integer boolean column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newIntBooleanColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.INTEGER, 0, 0, 0, allowsNull, null);
}
/**
* Returns a new integer boolean column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newIntBooleanColumn(String name, boolean allowsNull, Boolean defaultValue) throws SQLException {
return newColumn(name, Types.INTEGER, 0, 0, 0, allowsNull, null, defaultValue);
}
/**
* Returns a new flag boolean column. See newColumn(..) for the full docs.
* This might or might not work with your database, it's only tested with PostgreSQL
* and FrontBase.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newFlagBooleanColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.BOOLEAN, 0, 0, 0, allowsNull, null);
}
/**
* Returns a new flag boolean column. See newColumn(..) for the full docs.
* This might or might not work with your database, it's only tested with PostgreSQL
* and FrontBase.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newFlagBooleanColumn(String name, boolean allowsNull, Boolean defaultValue) throws SQLException {
return newColumn(name, Types.BOOLEAN, 0, 0, 0, allowsNull, null, defaultValue);
}
/**
* Returns a new string blob column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newClobColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.CLOB, 0, 0, 0, allowsNull, null);
}
/**
* Returns a new Blob column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newBlobColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.BLOB, 0, 0, 0, allowsNull, null);
}
/**
* Returns a new Blob column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param width the width of the blob
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newBlobColumn(String name, int width, boolean allowsNull) throws SQLException {
return newColumn(name, Types.BLOB, width, 0, 0, allowsNull, null);
}
/**
* Returns a new Blob column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param width the width of the blob
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newBlobColumn(String name, int width, boolean allowsNull, NSData defaultValue) throws SQLException {
return newColumn(name, Types.BLOB, width, 0, 0, allowsNull, null, defaultValue);
}
/**
* Returns a new timestamp column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newTimestampColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.TIMESTAMP, 0, 0, 0, allowsNull, ERXMigrationColumn.NULL_VALUE_TYPE);
}
/**
* Returns a new timestamp column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newTimestampColumn(String name, boolean allowsNull, NSTimestamp defaultValue) throws SQLException {
return newColumn(name, Types.TIMESTAMP, 0, 0, 0, allowsNull, ERXMigrationColumn.NULL_VALUE_TYPE, defaultValue);
}
/**
* Returns a new date column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newDateColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.DATE, 0, 0, 0, allowsNull, ERXMigrationColumn.NULL_VALUE_TYPE);
}
/**
* Returns a new date column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newDateColumn(String name, boolean allowsNull, NSTimestamp defaultValue) throws SQLException {
return newColumn(name, Types.DATE, 0, 0, 0, allowsNull, ERXMigrationColumn.NULL_VALUE_TYPE, defaultValue);
}
/**
* Returns a new time column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newTimeColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.TIME, 0, 0, 0, allowsNull, ERXMigrationColumn.NULL_VALUE_TYPE);
}
/**
* Returns a new ipaddress column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newIpAddressColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, CustomTypes.INET, 39, 0, 0, allowsNull, null);
}
/**
* Returns a new ipaddress column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @param defaultValue the default value of this column
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newIpAddressColumn(String name, boolean allowsNull, String defaultValue) throws SQLException {
return newColumn(name, CustomTypes.INET, 39, 0, 0, allowsNull, null, defaultValue);
}
/**
* Returns a new UUID column. See newColumn(..) for the full docs.
*
* @param name the name of the column
* @param allowsNull if true, the column will allow null values
* @return the new ERXMigrationColumn
* @throws SQLException if the column cannot be created
*/
public ERXMigrationColumn newUuidColumn(String name, boolean allowsNull) throws SQLException {
return newColumn(name, Types.BINARY, 16, 0, 0, allowsNull, null);
}
/**
* Callback method for ERXMigrationColumn to notify the table that
* it has been deleted.
*
* @param column the column that has been deleted
*/
public void _columnDeleted(ERXMigrationColumn column) {
_columns.removeObject(column);
}
/**
* Returns an array of EOSQLExpressions for creating this table and all of its ERXMigrationColumns.
*
* @return an array of EOSQLExpressions for creating this table
*/
@SuppressWarnings("unchecked")
public NSArray<EOSQLExpression> _createExpressions() {
EOSchemaGeneration schemaGeneration = _database.synchronizationFactory();
NSArray<EOSQLExpression> expressions = schemaGeneration.createTableStatementsForEntityGroup(new NSArray<>(_newEntity()));
ERXMigrationDatabase._ensureNotEmpty(expressions, "create table", true);
return expressions;
}
/**
* Executes the SQL operations to create this table.
*
* @throws SQLException if the creation fails
*/
public void create() throws SQLException {
if (_new) {
ERXJDBCUtilities.executeUpdateScript(_database.adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(_createExpressions()));
NSMutableArray<ERXMigrationColumn> primaryKeys = new NSMutableArray<>();
for (ERXMigrationColumn column : _columns) {
if (column.isPrimaryKey()) {
primaryKeys.addObject(column);
}
column._setNew(false);
}
if (primaryKeys.count() > 0) {
setPrimaryKey(true, primaryKeys.toArray(new ERXMigrationColumn[primaryKeys.count()]));
}
for (ERXMigrationForeignKey foreignKey : _foreignKeys) {
addForeignKey(true, foreignKey.sourceColumns(), foreignKey.destinationColumns());
}
for (ERXMigrationIndex index : _indexes) {
addIndex(true, index);
}
_new = false;
}
else {
log.warn("You called .create() on the table '{}', but it was already created.", _name);
}
}
/**
* Returns an array of EOSQLExpressions for dropping this table.
*
* @return an array of EOSQLExpressions for dropping this table
*/
@SuppressWarnings("unchecked")
public NSArray<EOSQLExpression> _dropExpressions() {
EOSchemaGeneration schemaGeneration = _database.synchronizationFactory();
NSArray<EOSQLExpression> expressions = schemaGeneration.dropTableStatementsForEntityGroup(new NSArray<>(_blankEntity()));
ERXMigrationDatabase._ensureNotEmpty(expressions, "drop table", true);
return expressions;
}
/**
* Executes the SQL operations to drop this table.
*
* @throws SQLException if the drop fails
*/
public void drop() throws SQLException {
ERXJDBCUtilities.executeUpdateScript(_database.adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(_dropExpressions()));
_database._tableDropped(this);
}
/**
* Returns an array of EOSQLExpressions for renaming this table.
*
* @param newName
* new table name
*
* @return an array of EOSQLExpressions for renaming this table
*/
@SuppressWarnings("unchecked")
public NSArray<EOSQLExpression> _renameToExpressions(String newName) {
EOSchemaSynchronization schemaSynchronization = _database.synchronizationFactory();
NSArray<EOSQLExpression> expressions = schemaSynchronization.statementsToRenameTableNamed(name(), newName, NSDictionary.EmptyDictionary);
ERXMigrationDatabase._ensureNotEmpty(expressions, "rename table", true);
return expressions;
}
/**
* Executes the SQL operations to rename this table.
*
* @param newName
* new table name
*
* @throws SQLException if the rename fails
*/
public void renameTo(String newName) throws SQLException {
ERXJDBCUtilities.executeUpdateScript(_database.adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(_renameToExpressions(newName)));
_setName(newName);
}
/**
* Returns an array of EOSQLExpressions for setting the primary key constraint of this table.
*
* @param columns
*
* @return an array of EOSQLExpressions for setting the primary key constraint of this table
*/
@SuppressWarnings("unchecked")
public NSArray<EOSQLExpression> _setPrimaryKeyExpressions(ERXMigrationColumn... columns) {
EOSchemaGeneration schemaGeneration = _database.synchronizationFactory();
EOEntity entity = columns[0].table()._blankEntity();
NSMutableArray<EOAttribute> attributes = new NSMutableArray<>();
for (ERXMigrationColumn column : columns) {
EOAttribute attribute = column._newAttribute(entity);
attributes.addObject(attribute);
}
entity.setPrimaryKeyAttributes(attributes);
NSArray<EOSQLExpression> expressions = schemaGeneration.primaryKeyConstraintStatementsForEntityGroup(new NSArray<>(entity));
ERXMigrationDatabase._ensureNotEmpty(expressions, "add primary key", true);
NSArray<EOSQLExpression> supportExpressions = schemaGeneration.primaryKeySupportStatementsForEntityGroup(new NSArray<>(entity));
return expressions.arrayByAddingObjectsFromArray(supportExpressions);
}
/**
* Executes the SQL operations to add this unique index.
*
* @param columnName the name of the column to add a unique index on
* @throws SQLException if the constraint fails
*/
public void addUniqueIndex(String columnName) throws SQLException {
addUniqueIndex(null, columnName);
}
/**
* Executes the SQL operations to add this unique index.
*
* @param indexName the name of the index
* @param columnName the name of the column to add a unique index on
* @throws SQLException if the constraint fails
*/
public void addUniqueIndex(String indexName, String columnName) throws SQLException {
addUniqueIndex(indexName, existingColumnNamed(columnName));
}
/**
* Executes the SQL operations to add this unique index.
*
* @param indexName the name of the index
* @param columnName the name of the column to add a unique index on
* @param width
* @throws SQLException if the constraint fails
*/
public void addUniqueIndex(String indexName, String columnName, int width) throws SQLException {
addUniqueIndex(indexName, new ERXSQLHelper.ColumnIndex(columnName, width));
}
/**
* Executes the SQL operations to add a unique index.
*
* @param indexName the name of the index
* @param columns the columns to add a unique index on
* @throws SQLException if the constraint fails
*/
public void addUniqueIndex(String indexName, ERXMigrationColumn... columns) throws SQLException {
ERXSQLHelper.ColumnIndex[] columnIndexes = _columnIndexesForMigrationColumns(columns);
addUniqueIndex(indexName, columnIndexes);
}
/**
* Executes the SQL operations to add a unique index.
*
* @param indexName the name of the index
* @param columnIndexes the column indexes to unique index on
* @throws SQLException if the constraint fails
*/
public void addUniqueIndex(String indexName, ERXSQLHelper.ColumnIndex... columnIndexes) throws SQLException {
addUniqueIndex(!_new, indexName, columnIndexes);
}
/**
* Executes the SQL operations to add a unique index.
*
* @param create if true, the index is created immediately
* @param indexName the name of the index
* @param columnIndexes the column indexes to unique index on
* @throws SQLException if the constraint fails
*/
public void addUniqueIndex(boolean create, String indexName, ERXSQLHelper.ColumnIndex... columnIndexes) throws SQLException {
if (create) {
ERXSQLHelper helper = ERXSQLHelper.newSQLHelper(_database.adaptorChannel());
if(indexName == null) {
indexName = _defaultIndexName(true, _name, helper.columnNamesFromColumnIndexes(columnIndexes).toArray(new String[] {}));
}
String sql = helper.sqlForCreateUniqueIndex(indexName, _name, columnIndexes);
ERXJDBCUtilities.executeUpdateScript(_database.adaptorChannel(), sql);
}
else {
_indexes.addObject(new ERXMigrationIndex(indexName, true, columnIndexes));
}
}
/**
* Executes the SQL operations to add this index.
*
* @param columnName the name of the column to add a unique index on
* @throws SQLException if the constraint fails
*/
public void addIndex(String columnName) throws SQLException {
addIndex(null, columnName);
}
/**
* Executes the SQL operations to add this index.
*
* @param indexName the name of the index
* @param columnName the name of the column to add a unique index on
* @throws SQLException if the constraint fails
*/
public void addIndex(String indexName, String columnName) throws SQLException {
addIndex(indexName, existingColumnNamed(columnName));
}
/**
* Executes the SQL operations to add this index.
*
* @param indexName the name of the index
* @param columnName the name of the column to add a unique index on
* @param width
* @throws SQLException if the constraint fails
*/
public void addIndex(String indexName, String columnName, int width) throws SQLException {
addIndex(indexName, new ERXSQLHelper.ColumnIndex(columnName, width));
}
/**
* Executes the SQL operations to add an index.
*
* @param indexName the name of the index
* @param columns the columns to add a unique index on
* @throws SQLException if the constraint fails
*/
public void addIndex(String indexName, ERXMigrationColumn... columns) throws SQLException {
ERXSQLHelper.ColumnIndex[] columnIndexes = _columnIndexesForMigrationColumns(columns);
addIndex(indexName, columnIndexes);
}
/**
* Executes the SQL operations to add an index.
*
* @param indexName the name of the index
* @param columnIndexes the column indexes to unique index on
* @throws SQLException if the constraint fails
*/
public void addIndex(String indexName, ERXSQLHelper.ColumnIndex... columnIndexes) throws SQLException {
addIndex(!_new, indexName, columnIndexes);
}
/**
* Executes the SQL operations to add an index.
*
* @param create if true, the index is created immediately
* @param indexName the name of the index
* @param columnIndexes the column indexes to unique index on
* @throws SQLException if the constraint fails
*/
public void addIndex(boolean create, String indexName, ERXSQLHelper.ColumnIndex... columnIndexes) throws SQLException {
if (create) {
ERXSQLHelper helper = ERXSQLHelper.newSQLHelper(_database.adaptorChannel());
if (indexName == null) {
indexName = _defaultIndexName(false, _name, helper.columnNamesFromColumnIndexes(columnIndexes).toArray(new String[] {}));
}
String sql = helper.sqlForCreateIndex(indexName, _name, columnIndexes);
ERXJDBCUtilities.executeUpdateScript(_database.adaptorChannel(), sql);
}
else {
_indexes.addObject(new ERXMigrationIndex(indexName, false, columnIndexes));
}
}
/**
* Executes the SQL operations to add an index.
*
* @param index the index to add
* @throws SQLException if the constraint fails
*/
public void addIndex(ERXMigrationIndex index) throws SQLException {
addIndex(!_new, index);
}
/**
* Executes the SQL operations to add an index.
*
* @param create if true, the index is created immediately
* @param index the index to add
* @throws SQLException if the constraint fails
*/
public void addIndex(boolean create, ERXMigrationIndex index) throws SQLException {
if (index.isUnique()) {
addUniqueIndex(create, index.name(), index.columns());
}
else {
addIndex(create, index.name(), index.columns());
}
}
private ERXSQLHelper.ColumnIndex[] _columnIndexesForMigrationColumns(ERXMigrationColumn... columns) {
ERXSQLHelper.ColumnIndex[] columnIndexes = new ERXSQLHelper.ColumnIndex[columns.length];
for (int columnNum = 0; columnNum < columns.length; columnNum ++) {
columnIndexes[columnNum] = new ERXSQLHelper.ColumnIndex(columns[columnNum].name(), columns[columnNum].width());
}
return columnIndexes;
}
private String _defaultIndexName(boolean unique, String tableName, String... columnNames) {
String indexName = unique ? "UNIQUE_" : "INDEX_";
indexName += tableName;
indexName += "__";
indexName += new NSArray<>(columnNames).componentsJoinedByString("_");
return indexName;
}
/**
* Executes the SQL operations to add this primary key constraint.
*
* @param columnName the name of the column to set as the primary key
* @throws SQLException if the constraint fails
*/
public void setPrimaryKey(String columnName) throws SQLException {
setPrimaryKey(existingColumnNamed(columnName));
}
/**
* Executes the SQL operations to add this primary key constraint.
*
* @param columnNames the names of the columns to set as the primary key
* @throws SQLException if the constraint fails
*/
public void setPrimaryKey(String... columnNames) throws SQLException {
ERXMigrationColumn[] columns = new ERXMigrationColumn[columnNames.length];
for (int i = 0; i < columnNames.length; i ++) {
columns[i] = existingColumnNamed(columnNames[i]);
}
setPrimaryKey(columns);
}
/**
* Executes the SQL operations to add this primary key constraint.
*
* @param columns the primary key columns to designate as primary keys
* @throws SQLException if the constraint fails
*/
public void setPrimaryKey(ERXMigrationColumn... columns) throws SQLException {
setPrimaryKey(!_new, columns);
}
/**
* Executes the SQL operations to add this primary key constraint.
*
* @param create if create is true, execute this now (vs just flag the ERXMigrationColumn)
* @param columns the primary key columns to designate as primary keys
* @throws SQLException if the constraint fails
*/
public void setPrimaryKey(boolean create, ERXMigrationColumn... columns) throws SQLException {
for (ERXMigrationColumn column : _columns) {
column._setPrimaryKey(false);
}
for (ERXMigrationColumn column : columns) {
column._setPrimaryKey(true);
}
if (create) {
ERXJDBCUtilities.executeUpdateScript(_database.adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(_setPrimaryKeyExpressions(columns)));
}
}
/**
* Adds a pending foreign key to this table.
*
* @param foreignKey the new foreign key
*/
public void _addForeignKey(ERXMigrationForeignKey foreignKey) {
_foreignKeys.addObject(foreignKey);
}
/**
* Returns an array of EOSQLExpressions for adding a foreign key constraint to this table.
*
* @param sourceColumn the source column of the relationship
* @param destinationColumn the destination columns of the relationship (should be the PK of the destination table)
* @return an array of EOSQLExpressions for adding a foreign key constraint to this table
*/
@SuppressWarnings("unchecked")
public NSArray<EOSQLExpression> _addForeignKeyExpressions(ERXMigrationColumn sourceColumn, ERXMigrationColumn destinationColumn) {
EOSchemaGeneration schemaGeneration = _database.synchronizationFactory();
NSArray<EOSQLExpression> expressions = schemaGeneration.foreignKeyConstraintStatementsForRelationship(_newRelationship(new ERXMigrationColumn[] { sourceColumn }, new ERXMigrationColumn[] { destinationColumn }));
ERXMigrationDatabase._ensureNotEmpty(expressions, "add foreign key", false);
return expressions;
}
/**
* Returns an array of EOSQLExpressions for adding a foreign key constraint to this table. The source and destination
* arrays should be ordered so that corresponding indexes in the source and destination arrays match up.
*
* @param sourceColumns the source columns of the relationship
* @param destinationColumns the destination columns of the relationship (should be the PKs of the destination table)
* @return an array of EOSQLExpressions for adding a foreign key constraint to this table
*/
@SuppressWarnings("unchecked")
public NSArray<EOSQLExpression> _addForeignKeyExpressions(ERXMigrationColumn[] sourceColumns, ERXMigrationColumn[] destinationColumns) {
EOSchemaGeneration schemaGeneration = _database.synchronizationFactory();
NSArray<EOSQLExpression> expressions = schemaGeneration.foreignKeyConstraintStatementsForRelationship(_newRelationship(sourceColumns, destinationColumns));
ERXMigrationDatabase._ensureNotEmpty(expressions, "add foreign key", false);
return expressions;
}
/**
* Executes the SQL operations to add this foreign key constraint (only supports single attribute FK's right now).
*
* @param sourceColumnName the source column name of the relationship
* @param destinationTableName the destination table of the relationship (should be the PK of the destination table)
* @param destinationColumnName the destination column of the relationship (should be the PK of the destination table)
* @throws SQLException if the add fails
*/
public void addForeignKey(String sourceColumnName, String destinationTableName, String destinationColumnName) throws SQLException {
addForeignKey(existingColumnNamed(sourceColumnName), database().existingColumnNamed(destinationTableName, destinationColumnName));
}
/**
* Executes the SQL operations to add this foreign key constraint.
*
* @param sourceColumnName the source column name of the relationship
* @param destinationColumn the destination column of the relationship (should be the PK of the destination table)
* @throws SQLException if the add fails
*/
public void addForeignKey(String sourceColumnName, ERXMigrationColumn destinationColumn) throws SQLException {
addForeignKey(existingColumnNamed(sourceColumnName), destinationColumn);
}
/**
* Executes the SQL operations to add this foreign key constraint.
*
* @param sourceColumn the source column of the relationship
* @param destinationColumn the destination column of the relationship (should be the PK of the destination table)
* @throws SQLException if the add fails
*/
public void addForeignKey(ERXMigrationColumn sourceColumn, ERXMigrationColumn destinationColumn) throws SQLException {
addForeignKey(!_new, sourceColumn, destinationColumn);
}
/**
* Executes the SQL operations to add this foreign key constraint.
*
* @param sourceColumns the source columns of the relationship
* @param destinationColumns the destination columns of the relationship (should be the PKs of the destination table)
* @throws SQLException if the add fails
*/
public void addForeignKey(ERXMigrationColumn[] sourceColumns, ERXMigrationColumn[] destinationColumns) throws SQLException {
addForeignKey(!_new, sourceColumns, destinationColumns);
}
/**
* Executes the SQL operations to add this foreign key constraint.
*
* @param create if create is true, execute this now (vs just flag the ERXMigrationColumn)
* @param sourceColumn the source column of the relationship
* @param destinationColumn the destination column of the relationship (should be the PK of the destination table)
* @throws SQLException if the add fails
*/
public void addForeignKey(boolean create, ERXMigrationColumn sourceColumn, ERXMigrationColumn destinationColumn) throws SQLException {
addForeignKey(create, new ERXMigrationColumn[] { sourceColumn }, new ERXMigrationColumn[] { destinationColumn });
}
/**
* Executes the SQL operations to add this foreign key constraint.
*
* @param create if create is true, execute this now (vs just flag the ERXMigrationColumn)
* @param sourceColumns the source columns of the relationship
* @param destinationColumns the destination columns of the relationship (should be the PKs of the destination table)
* @throws SQLException if the add fails
*/
public void addForeignKey(boolean create, ERXMigrationColumn[] sourceColumns, ERXMigrationColumn[] destinationColumns) throws SQLException {
if (create) {
NSArray<EOSQLExpression> expressions = _addForeignKeyExpressions(sourceColumns, destinationColumns);
if (expressions != null) {
ERXJDBCUtilities.executeUpdateScript(_database.adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(expressions));
}
}
else {
_addForeignKey(new ERXMigrationForeignKey(sourceColumns, destinationColumns));
}
}
/**
* Returns an array of EOSQLExpressions for removing the primary key constraint of this table (only supports single attribute PK's right now).
*
* @param columns the primary key columns to drop
* @return an array of EOSQLExpressions for removing the primary key constraint of this table
*/
@SuppressWarnings("unchecked")
public NSArray<EOSQLExpression> _dropPrimaryKeyExpressions(ERXMigrationColumn... columns) {
EOSchemaGeneration schemaGeneration = _database.synchronizationFactory();
EOEntity entity = columns[0].table()._blankEntity();
NSMutableArray<EOAttribute> attributes = new NSMutableArray<>();
for (ERXMigrationColumn column : columns) {
EOAttribute attribute = column._newAttribute(entity);
attributes.addObject(attribute);
}
entity.setPrimaryKeyAttributes(attributes);
NSArray<EOSQLExpression> expressions = schemaGeneration.dropPrimaryKeySupportStatementsForEntityGroup(new NSArray<>(entity));
ERXMigrationDatabase._ensureNotEmpty(expressions, "drop primary key", true);
return expressions;
}
/**
* Executes the SQL operations to drop this primary key constraint (only supports single attribute PK's right now).
*
* @param columns the primary key columns
* @throws SQLException if the drop fails
*/
public void dropPrimaryKey(ERXMigrationColumn... columns) throws SQLException {
ERXJDBCUtilities.executeUpdateScript(_database.adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(_dropPrimaryKeyExpressions(columns)));
for (ERXMigrationColumn column : columns) {
column._setPrimaryKey(false);
}
}
/**
* Returns a dictionary that represents the primary key for
* an entity described by this table. Note that you must have specified
* the primary key columns for this table prior to calling this method via
* the setPrimaryKeys method (or calling _setPrimaryKey on the individual
* columns).
*
* @return a dictionary of a primary key
*/
public NSDictionary<String, Object> newPrimaryKey() {
return newPrimaryKeys(1).lastObject();
}
/**
* Returns an array of dictionaries that represent the primary keys for
* an entity described by this table. Note that you must have specified
* the primary key columns for this table prior to calling this method via
* the setPrimaryKeys method (or calling _setPrimaryKey on the individual
* columns).
*
* @param count the number of primary keys desired
* @return an array of dictionaries of primary keys
*/
@SuppressWarnings("unchecked")
public NSArray<NSDictionary<String, Object>> newPrimaryKeys(int count) {
NSArray<NSDictionary<String, Object>> primaryKeys = database().adaptorChannel().primaryKeysForNewRowsWithEntity(count, _newEntity());
//NSMutableArray<NSMutableDictionary<String, Object>>
return primaryKeys;
}
}