Package er.extensions.migration

Source Code of er.extensions.migration.ERXMigrationColumn$_ColumnType

package er.extensions.migration;

import java.sql.SQLException;

import com.webobjects.eoaccess.EOAdaptor;
import com.webobjects.eoaccess.EOAttribute;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.eoaccess.EOSQLExpression;
import com.webobjects.eoaccess.EOSchemaSynchronization;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableDictionary;
import com.webobjects.jdbcadaptor.JDBCAdaptor;

import er.extensions.jdbc.ERXJDBCUtilities;
import er.extensions.jdbc.ERXSQLHelper;

/**
* ERXMigrationColumn is conceptually equivalent to an EOAttribute in the
* ERXMigrationXxx model. To obtain an ERXMigrationColumn, call
* ERXMigrationTable.newXxxColumn(..).
*
* @author mschrag
*/
public class ERXMigrationColumn {
  public static final String NULL_VALUE_TYPE = "___NULL_VALUE_TYPE___";

  /**
   * Constant for use with ERXMigrationTable.newXxxColumn AllowsNull columns.
   */
  public static final boolean AllowsNull = true;

  /**
   * Constant for use with ERXMigrationTable.newXxxColumn NotNull columns.
   */
  public static final boolean NotNull = false;
 
  private ERXMigrationTable _table;
  private String _name;
  private int _jdbcType;
  private int _width;
  private int _precision;
  private int _scale;
  private boolean _allowsNull;
  private Object _defaultValue;
  private boolean _new;
  private String _overrideValueType;
  private String _overrideExternalType;
 
  private boolean _primaryKey;

  /**
   * Constructs a new ERXMigrationColumn.
   *
   * @param table
   *            the parent 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
   *            this will set the "Default" hint in the EOAttribute's userInfo
   *            dictionary (your plugin must support this)
   */
  protected ERXMigrationColumn(ERXMigrationTable table, String name, int jdbcType, int width, int precision, int scale, boolean allowsNull, String overrideValueType, Object defaultValue) {
    _table = table;
    _name = name;
    _jdbcType = jdbcType;
    _width = width;
    _precision = precision;
    _scale = scale;
    _allowsNull = allowsNull;
    _overrideValueType = overrideValueType;
    _defaultValue = defaultValue;
    _new = true;
  }

  /**
   * Returns the parent ERXMigrationTable of this column.
   *
   * @return the parent ERXMigrationTable of this column
   */
  public ERXMigrationTable table() {
    return _table;
  }

  /**
   * Sets the name of this column. This does not perform a column rename
   * operation.
   *
   * @param name
   *            the name of this column
   */
  public void _setName(String name) {
    _name = name;
  }

  /**
   * Returns the name of this column.
   *
   * @return the name of this column
   */
  public String name() {
    return _name;
  }

  /**
   * Sets the width of this column. This does not perform a column resize
   * operation.
   *
   * @param width
   *            the width of this column
   */
  public void _setWidth(int width) {
    _width = width;
  }

  /**
   * Returns the width of this column.
   *
   * @return the width of this column
   */
  public int width() {
    return _width;
  }

  /**
   * Sets whether or not this column allows nulls. This does not perform a
   * column change operation.
   *
   * @param allowsNull
   *            if true, this column allows nulls
   */
  public void _setAllowsNull(boolean allowsNull) {
    _allowsNull = allowsNull;
  }

  /**
   * Returns the width of this column.
   *
   * @return the width of this column
   */
  public boolean allowsNull() {
    return _allowsNull;
  }

  /**
   * Sets the precision of this column. This does not perform a column change
   * operation.
   *
   * @param precision
   *            the precision of this column
   */
  public void _setPrecision(int precision) {
    _precision = precision;
  }

  /**
   * Returns the precision of this column.
   *
   * @return the precision of this column
   */
  public int precision() {
    return _precision;
  }

  /**
   * Sets the scale of this column. This does not perform a column change
   * operation.
   *
   * @param scale
   *            the scale of this column
   */
  public void _setScale(int scale) {
    _scale = scale;
  }

  /**
   * Returns the scale of this column.
   *
   * @return the scale of this column
   */
  public int scale() {
    return _scale;
  }

  /**
   * Overrides the external type of this column.
   *
   * @param overrideExternalType
   *            the external type to override
   */
  public void _setOverrideExternalType(String overrideExternalType) {
    _overrideExternalType = overrideExternalType;
  }

  /**
   * Returns the external type of this column (or null if there is no
   * override).
   *
   * @return the external type of this column
   */
  public String overrideExternalType() {
    return _overrideExternalType;
  }

  /**
   * Sets the value type for the underlying attribute for this column.
   *
   * @param overrideValueType
   *            the value type for the underlying attribute for this column
   */
  public void _setOverrideValueType(String overrideValueType) {
    _overrideValueType = overrideValueType;
  }

  /**
   * Returns the value type associated with the underlying attribute (or null
   * to have this autoselected).
   *
   * @return the value type associated with the underlying attribute
   */
  public String overrideValueType() {
    return _overrideValueType;
  }

  /**
   * Sets the default value of this column.
   *
   * @param defaultValue
   *            the default value of this column
   */
  public void setDefaultValue(Object defaultValue) {
    _defaultValue = defaultValue;
  }

  /**
   * Returns the default value of this column.
   *
   * @return the default value of this column
   */
  public Object defaultValue() {
    return _defaultValue;
  }
 
  /**
   * Sets whether or not this column is a primary key.
   *
   * @param primaryKey whether or not this column is a primary key
   */
  public void _setPrimaryKey(boolean primaryKey) {
    _primaryKey = primaryKey;
  }
 
  /**
   * Returns whether or not this column is a primary key (note this
   * is only valid if you told migrations that this column is a
   * primary key).
   *
   * @return whether or not this column is a primary key
   */
  public boolean isPrimaryKey() {
    return _primaryKey;
  }

  /**
   * Returns true if this column has not yet been created in the database.
   *
   * @return if this column has not yet been created in the database
   */
  public boolean isNew() {
    return _new;
  }

  /**
   * Sets whether or not this column has been created in the database.
   *
   * @param isNew
   *            if true, the column has been created
   */
  public void _setNew(boolean isNew) {
    _new = isNew;
  }

  /**
   * Returns an EOAttribute with all of its fields filled in based on the
   * properties of this ERXMigrationColumn. The attribute is attached to a
   * table._blankEntity().
   *
   * @return an EOAttribute with all of its fields filled in
   */
  public EOAttribute _newAttribute() {
    return _newAttribute(_table._blankEntity());
  }

  /**
   * Returns an EOAttribute with all of its fields filled in based on the
   * properties of this ERXMigrationColumn. The attribute is attached to the
   * given entity.
   *
   * @param entity
   *            the entity to add the attribute to
   * @return an EOAttribute with all of its fields filled in
   */
  @SuppressWarnings("unchecked")
  public EOAttribute _newAttribute(EOEntity entity) {
    EOAdaptor eoAdaptor = _table.database().adaptor();
    // MS: Hack to make Memory adaptor migrations "work"
    if (!(eoAdaptor instanceof JDBCAdaptor)) {
      EOAttribute nonJdbcAttribute = new EOAttribute();
      nonJdbcAttribute.setName(_name);
      nonJdbcAttribute.setColumnName(_name);
      nonJdbcAttribute.setExternalType("nonJdbcAttribute");
    entity.addAttribute(nonJdbcAttribute);
      return nonJdbcAttribute;
    }
   
    JDBCAdaptor adaptor = (JDBCAdaptor)_table.database().adaptor();
    ERXSQLHelper sqlHelper = ERXSQLHelper.newSQLHelper(adaptor);
    String externalType = sqlHelper.externalTypeForJDBCType(adaptor, _jdbcType);
    if (externalType == null) {
      externalType = "IF_YOU_ARE_SEEING_THIS_SOMETHING_WENT_WRONG_WITH_EXTERNAL_TYPES";
    }
    EOAttribute attribute = adaptor.createAttribute(_name, _name, _jdbcType, externalType, _precision, _scale, _allowsNull ? 1 : 0);
    if (_width > 0) {
      attribute.setWidth(_width);
    }
    if (_defaultValue != null) {
      NSDictionary userInfo = attribute.userInfo();
      NSMutableDictionary mutableUserInfo;
      if (userInfo == null) {
        mutableUserInfo = new NSMutableDictionary();
      }
      else {
        mutableUserInfo = userInfo.mutableClone();
      }
      mutableUserInfo.setObjectForKey(_defaultValue, "default");
      attribute.setUserInfo(mutableUserInfo);
    }

    if (_overrideValueType != null) {
      if (ERXMigrationColumn.NULL_VALUE_TYPE.equals(_overrideValueType)) {
        attribute.setValueType(null);
      }
      else {
        attribute.setValueType(_overrideValueType);
      }
      if (sqlHelper.reassignExternalTypeForValueTypeOverride(attribute)) {
        adaptor.assignExternalTypeForAttribute(attribute);
      }
    }

    if (_overrideExternalType != null) {
      attribute.setExternalType(_overrideExternalType);
    }

    entity.addAttribute(attribute);
    return attribute;
  }

  /**
   * Returns an array of EOSQLExpressions for creating this column.
   *
   * @return an array of EOSQLExpressions for creating this column
   */
  @SuppressWarnings("unchecked")
  public NSArray<EOSQLExpression> _createExpressions() {
    EOSchemaSynchronization schemaSynchronization = _table.database().synchronizationFactory();
    NSArray<EOSQLExpression> expressions = schemaSynchronization.statementsToInsertColumnForAttribute(_newAttribute(), NSDictionary.EmptyDictionary);
    ERXMigrationDatabase._ensureNotEmpty(expressions, "add column", true);
    return expressions;
  }

  /**
   * Executes the SQL operations to create this column.
   *
   * @throws SQLException
   *             if the creation fails
   */
  public void create() throws SQLException {
    if (_new) {
      ERXJDBCUtilities.executeUpdateScript(_table.database().adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(_createExpressions()));
      _new = false;
    }
    else {
      ERXMigrationDatabase.log.warn("You called .create() on the column '" + _name + "', but it was already created.");
    }
  }

  /**
   * Returns an array of EOSQLExpressions for deleting this column.
   *
   * @return an array of EOSQLExpressions for deleting this column
   */
  @SuppressWarnings("unchecked")
  public NSArray<EOSQLExpression> _deleteExpressions() {
    EOSchemaSynchronization schemaSynchronization = _table.database().synchronizationFactory();
    NSArray<EOSQLExpression> expressions = schemaSynchronization.statementsToDeleteColumnNamed(name(), _table.name(), NSDictionary.EmptyDictionary);
    ERXMigrationDatabase._ensureNotEmpty(expressions, "delete column", true);
    return expressions;
  }

  /**
   * Executes the SQL operations to delete this column.
   *
   * @throws SQLException
   *             if the delete fails
   */
  public void delete() throws SQLException {
    ERXJDBCUtilities.executeUpdateScript(_table.database().adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(_deleteExpressions()));
    _table._columnDeleted(this);
  }

  /**
   * Returns an array of EOSQLExpressions for renaming this column.
   *
   * @param newName
   *            the new name of this column
   * @return an array of EOSQLExpressions for renaming this column
   */
  @SuppressWarnings("unchecked")
  public NSArray<EOSQLExpression> _renameToExpressions(String newName) {
    EOSchemaSynchronization schemaSynchronization = _table.database().synchronizationFactory();
    NSArray<EOSQLExpression> expressions = schemaSynchronization.statementsToRenameColumnNamed(name(), _table.name(), newName, NSDictionary.EmptyDictionary);
    ERXMigrationDatabase._ensureNotEmpty(expressions, "rename column", true);
    _setName(newName);
    return expressions;
  }

  /**
   * Executes the SQL operations to rename this column.
   *
   * @param newName
   *            the new name of this column
   * @throws SQLException
   *             if the rename fails
   */
  public void renameTo(String newName) throws SQLException {
    ERXJDBCUtilities.executeUpdateScript(_table.database().adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(_renameToExpressions(newName)));
  }

  /**
   * Changes the "allows null" state of this column.
   *
   * @param allowsNull
   *            if true, this column allows nulls
   * @throws SQLException
   *             if the change fails
   */
  @SuppressWarnings("unchecked")
  public void setAllowsNull(boolean allowsNull) throws SQLException {
    EOSchemaSynchronization schemaSynchronization = _table.database().synchronizationFactory();
    NSArray<EOSQLExpression> expressions = schemaSynchronization.statementsToModifyColumnNullRule(name(), _table.name(), allowsNull, NSDictionary.EmptyDictionary);
    ERXMigrationDatabase._ensureNotEmpty(expressions, "modify allows null", true);
    ERXJDBCUtilities.executeUpdateScript(_table.database().adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(expressions));
  }

  /**
   * Changes the data type of this column.
   *
   * @param jdbcType
   *            the new JDBC type of the column (see java.sql.Types)
   * @param scale
   *            the new scale
   * @param precision
   *            the new precision
   * @param width
   *            the new width
   * @param options
   *            the options to use for conversion (or null)
   * @throws SQLException
   *             if the change fails
   */
  @SuppressWarnings("unchecked")
  public void setDataType(int jdbcType, int scale, int precision, int width, NSDictionary options) throws SQLException {
    JDBCAdaptor adaptor = (JDBCAdaptor) _table.database().adaptor();
    String externalType = ERXSQLHelper.newSQLHelper(adaptor).externalTypeForJDBCType(adaptor, jdbcType);
    EOSchemaSynchronization schemaSynchronization = _table.database().synchronizationFactory();
    NSArray<EOSQLExpression> expressions = schemaSynchronization.statementsToConvertColumnType(_name, _table.name(), null, new _ColumnType(externalType, scale, precision, width), options);
    ERXMigrationDatabase._ensureNotEmpty(expressions, "convert column type", true);
    ERXJDBCUtilities.executeUpdateScript(_table.database().adaptorChannel(), ERXMigrationDatabase._stringsForExpressions(expressions));
    _jdbcType = jdbcType;
    _scale = scale;
    _precision = precision;
    _width = width;
  }

  /**
   * Changes the data type of this column to a type that has a width.
   *
   * @param jdbcType
   *            the new JDBC type of the column (see java.sql.Types)
   * @param width
   *            the new width
   * @param options
   *            the options to use for conversion (or null)
   * @throws SQLException
   *             if the change fails
   */
  public void setWidthType(int jdbcType, int width, NSDictionary options) throws SQLException {
    setDataType(jdbcType, 0, 0, width, options);
  }

  /**
   * Changes the data type of this column to a new numeric type.
   *
   * @param jdbcType
   *            the new JDBC type of the column (see java.sql.Types)
   * @param scale
   *            the new scale
   * @param precision
   *            the new precision
   * @param options
   *            the options to use for conversion (or null)
   * @throws SQLException
   *             if the change fails
   */
  public void setNumericType(int jdbcType, int scale, int precision, NSDictionary options) throws SQLException {
    setDataType(jdbcType, scale, precision, 0, options);
  }

  /**
   * Implements EOSchemaSynchronization.ColumnTypes
   *
   * @author mschrag
   */
  public static class _ColumnType implements EOSchemaSynchronization.ColumnTypes {
    private String _name;
    private int _scale;
    private int _precision;
    private int _width;

    public _ColumnType(String name, int scale, int precision, int width) {
      _name = name;
      _scale = scale;
      _precision = precision;
      _width = width;
    }

    public String name() {
      return _name;
    }

    public int precision() {
      return _precision;
    }

    public int scale() {
      return _scale;
    }

    public int width() {
      return _width;
    }

  }
}
TOP

Related Classes of er.extensions.migration.ERXMigrationColumn$_ColumnType

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.