| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openjpa.jdbc.schema; |
| |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| import java.sql.DatabaseMetaData; |
| import java.sql.Date; |
| import java.sql.Time; |
| import java.sql.Timestamp; |
| import java.sql.Types; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.apache.openjpa.jdbc.identifier.DBIdentifier; |
| import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier; |
| import org.apache.openjpa.jdbc.meta.JavaSQLTypes; |
| import org.apache.openjpa.jdbc.meta.VersionStrategy; |
| import org.apache.openjpa.jdbc.sql.DBDictionary; |
| import org.apache.openjpa.lib.util.StringUtil; |
| import org.apache.openjpa.meta.JavaTypes; |
| |
| /** |
| * Represents a database column. Closely aligned with the column |
| * information available from {@link DatabaseMetaData}. |
| * |
| * @author Abe White |
| * @author Stephen Kim |
| */ |
| public class Column extends ReferenceCounter { |
| private static final long serialVersionUID = 1L; |
| public static final int FLAG_UNINSERTABLE = 2 << 0; |
| public static final int FLAG_UNUPDATABLE = 2 << 1; |
| public static final int FLAG_DIRECT_INSERT = 2 << 2; |
| public static final int FLAG_DIRECT_UPDATE = 2 << 3; |
| public static final int FLAG_FK_INSERT = 2 << 4; |
| public static final int FLAG_FK_UPDATE = 2 << 5; |
| public static final int FLAG_PK_JOIN = 2 << 6; |
| |
| private DBIdentifier _name = DBIdentifier.NULL; |
| private Table _table = null; |
| private DBIdentifier _tableName = DBIdentifier.NULL; |
| private DBIdentifier _schemaName = DBIdentifier.NULL; |
| private int _type = Types.OTHER; |
| private DBIdentifier _typeName = DBIdentifier.NULL; |
| private int _javaType = JavaTypes.OBJECT; |
| private int _size = 0; |
| private int _precision = -1; |
| private int _scale = -1; |
| private int _radix = 10; |
| private int _decimals = 0; |
| private String _defaultStr = null; |
| private Object _default = null; |
| private Boolean _notNull = null; |
| private boolean _autoAssign = false; |
| private boolean _rel = false; |
| private boolean _implicitRelation = false; |
| private DBIdentifier _target = DBIdentifier.NULL; |
| private String _targetField = null; |
| private int _flags = 0; |
| private QualifiedDBIdentifier _fullPath = null; |
| |
| private int _index = 0; |
| private boolean _pk = false; |
| private VersionStrategy _versionStrategy = null; |
| private String _comment = null; |
| private boolean _XML = false; |
| private boolean _isUni1MFK = false; |
| private Set<Constraint> _constraints = new HashSet<>(); |
| |
| /** |
| * Default constructor. |
| */ |
| public Column() { |
| } |
| |
| /** |
| * Constructor. |
| * |
| * @param name the name of the column |
| * @param table the column's table |
| * @deprecated |
| */ |
| @Deprecated |
| public Column(String name, Table table) { |
| this(DBIdentifier.newColumn(name), table); |
| } |
| |
| public Column(DBIdentifier name, Table table) { |
| setIdentifier(name); |
| if (table != null) { |
| setTableIdentifier(table.getIdentifier()); |
| setSchemaIdentifier(table.getSchemaIdentifier()); |
| } |
| _table = table; |
| } |
| |
| /** |
| * Called when the column is removed from its table. Removes the column |
| * from all table constraints and indexes, then invalidates it. |
| */ |
| void remove() { |
| Table table = getTable(); |
| if (table == null) |
| return; |
| |
| Schema schema = table.getSchema(); |
| if (schema != null && schema.getSchemaGroup() != null) { |
| Schema[] schemas = schema.getSchemaGroup().getSchemas(); |
| Table[] tabs; |
| ForeignKey[] fks; |
| Column[] cols; |
| Column[] pks; |
| for (int i = 0; i < schemas.length; i++) { |
| tabs = schemas[i].getTables(); |
| for (int j = 0; j < tabs.length; j++) { |
| fks = tabs[j].getForeignKeys(); |
| for (int k = 0; k < fks.length; k++) { |
| cols = fks[k].getColumns(); |
| pks = fks[k].getPrimaryKeyColumns(); |
| for (int l = 0; l < cols.length; l++) |
| if (this.equals(cols[l]) || this.equals(pks[l])) |
| fks[k].removeJoin(cols[l]); |
| |
| cols = fks[k].getConstantColumns(); |
| for (int l = 0; l < cols.length; l++) |
| if (this.equals(cols[l])) |
| fks[k].removeJoin(cols[l]); |
| |
| pks = fks[k].getConstantPrimaryKeyColumns(); |
| for (int l = 0; l < pks.length; l++) |
| if (this.equals(pks[l])) |
| fks[k].removeJoin(pks[l]); |
| |
| if (fks[k].getColumns().length == 0 |
| && fks[k].getConstantColumns().length == 0) |
| tabs[j].removeForeignKey(fks[k]); |
| } |
| } |
| } |
| } |
| |
| Index[] idxs = table.getIndexes(); |
| for (int i = 0; i < idxs.length; i++) |
| if (idxs[i].removeColumn(this) && idxs[i].getColumns().length == 0) |
| table.removeIndex(idxs[i]); |
| |
| Unique[] unqs = table.getUniques(); |
| for (int i = 0; i < unqs.length; i++) |
| if (unqs[i].removeColumn(this) && unqs[i].getColumns().length == 0) |
| table.removeUnique(unqs[i]); |
| |
| PrimaryKey pk = table.getPrimaryKey(); |
| if (pk != null && pk.removeColumn(this) && pk.getColumns().length == 0) |
| table.removePrimaryKey(); |
| |
| _table = null; |
| } |
| |
| /** |
| * Return the table for the column. |
| */ |
| public Table getTable() { |
| return _table; |
| } |
| |
| /** |
| * The column's table name. |
| * @deprecated |
| */ |
| @Deprecated |
| public String getTableName() { |
| return getTableIdentifier().getName(); |
| } |
| |
| public DBIdentifier getTableIdentifier() { |
| return _tableName == null ? DBIdentifier.NULL : _tableName; |
| } |
| |
| /** |
| * The column's table name. You can only call this method on columns |
| * whose table object is not set. |
| * @deprecated |
| */ |
| @Deprecated |
| public void setTableName(String name) { |
| setTableIdentifier(DBIdentifier.newTable(name)); |
| } |
| |
| public void setTableIdentifier(DBIdentifier name) { |
| if (getTable() != null) |
| throw new IllegalStateException(); |
| _tableName = name == null ? DBIdentifier.NULL : name; |
| _fullPath = null; |
| } |
| |
| /** |
| * Reset the table name with the fully qualified table name which |
| * includes the schema name |
| * @deprecated |
| */ |
| @Deprecated |
| public void resetTableName(String name) { |
| _tableName = DBIdentifier.newTable(name); |
| } |
| |
| public void resetTableIdentifier(DBIdentifier table) { |
| _tableName = table == null ? DBIdentifier.NULL : table; |
| } |
| |
| /** |
| * The column's schema name. |
| * @deprecated |
| */ |
| @Deprecated |
| public String getSchemaName() { |
| return getSchemaIdentifier().getName(); |
| } |
| |
| public DBIdentifier getSchemaIdentifier() { |
| return _schemaName == null ? DBIdentifier.NULL : _schemaName; |
| } |
| |
| /** |
| * The column's schema name. You can only call this method on columns |
| * whose table object is not set. |
| * @deprecated use setSchemaIdentifier(DBIdentifier name) |
| */ |
| @Deprecated |
| public void setSchemaName(String name) { |
| setSchemaIdentifier(DBIdentifier.newSchema(name)); |
| } |
| |
| public void setSchemaIdentifier(DBIdentifier name) { |
| if (getTable() != null) |
| throw new IllegalStateException(); |
| _schemaName = name == null ? DBIdentifier.NULL : name; |
| } |
| |
| /** |
| * Return the column's name. |
| * @deprecated use getIdentifier() |
| */ |
| @Deprecated |
| public String getName() { |
| return getIdentifier().getName(); |
| } |
| |
| public DBIdentifier getIdentifier() { |
| return _name == null ? DBIdentifier.NULL : _name; |
| } |
| |
| |
| /** |
| * Set the column's name. You can only call this method on columns |
| * whose table object is not set. |
| * @deprecated use setIdentifier(DBIdentifier name) |
| */ |
| @Deprecated |
| public void setName(String name) { |
| setIdentifier(DBIdentifier.newColumn(name)); |
| } |
| |
| public void setIdentifier(DBIdentifier name) { |
| if (getTable() != null) |
| throw new IllegalStateException(); |
| _name = name == null ? DBIdentifier.NULL : name; |
| _fullPath = null; |
| } |
| |
| /** |
| * Return the column's full name, in the form <table>.<name>. |
| * @deprecated use getFullDBIdentifier() |
| */ |
| @Deprecated |
| public String getFullName() { |
| return getFullDBIdentifier().getName(); |
| } |
| |
| public DBIdentifier getFullDBIdentifier() { |
| return getQualifiedPath().getIdentifier(); |
| } |
| |
| public QualifiedDBIdentifier getQualifiedPath() { |
| if (_fullPath == null) { |
| _fullPath = QualifiedDBIdentifier.newPath(getTableIdentifier(), getIdentifier() ); |
| } |
| return _fullPath; |
| } |
| |
| /** |
| * Return the column's SQL type. This will be one of the type constants |
| * defined in {@link Types}. |
| */ |
| public int getType() { |
| return _type; |
| } |
| |
| /** |
| * Set the column's SQL type. This should be one of the type constants |
| * defined in {@link Types}. |
| */ |
| public void setType(int sqlType) { |
| _type = sqlType; |
| } |
| |
| /** |
| * The database-specific SQL type of this column. |
| * @deprecated |
| */ |
| @Deprecated |
| public String getTypeName() { |
| return getTypeIdentifier().getName(); |
| } |
| |
| public DBIdentifier getTypeIdentifier() { |
| return _typeName == null ? DBIdentifier.NULL : _typeName ; |
| } |
| |
| /** |
| * The database-specific SQL type of this column. |
| * @deprecated |
| */ |
| @Deprecated |
| public void setTypeName(String typeName) { |
| setTypeIdentifier(DBIdentifier.newColumnDefinition(typeName)); |
| } |
| |
| public void setTypeIdentifier(DBIdentifier typeName) { |
| _typeName = typeName == null ? DBIdentifier.NULL : typeName; |
| } |
| |
| /** |
| * The Java type the data in this column is treated as, from |
| * {@link JavaTypes} or {@link JavaSQLTypes}. |
| */ |
| public int getJavaType() { |
| return _javaType; |
| } |
| |
| /** |
| * The Java type the data in this column is treated as, from |
| * {@link JavaTypes} or {@link JavaSQLTypes}. |
| */ |
| public void setJavaType(int type) { |
| _javaType = type; |
| } |
| |
| /** |
| * Return the column's size. |
| */ |
| public int getSize() { |
| return _size; |
| } |
| |
| /** |
| * Set the column's size. |
| */ |
| public void setSize(int size) { |
| _size = size; |
| } |
| |
| /** |
| * Return the number of decimal digits for the column, if applicable. |
| */ |
| public int getDecimalDigits() { |
| return _decimals; |
| } |
| |
| /** |
| * Set the number of decimal digits for the column. |
| */ |
| public void setDecimalDigits(int digits) { |
| _decimals = digits; |
| } |
| |
| public int getPrecision() { |
| return _precision; |
| } |
| |
| public void setPrecision(int p) { |
| _precision = p; |
| } |
| |
| public int getScale() { |
| return _scale; |
| } |
| |
| public void setScale(int s) { |
| _scale = s; |
| } |
| public int getRadix() { |
| return _radix; |
| } |
| |
| public void setRadix(int r) { |
| _radix = r; |
| } |
| |
| /** |
| * Return the default value set for the column, if any. |
| */ |
| public String getDefaultString() { |
| return _defaultStr; |
| } |
| |
| /** |
| * Set the default value for the column. |
| */ |
| public void setDefaultString(String def) { |
| _defaultStr = def; |
| _default = null; |
| } |
| |
| /** |
| * Return the default value set for this column, if any. If only a default |
| * string has been set, attempts to convert it to the right type based |
| * on the Java type set for this column. |
| */ |
| public Object getDefault() { |
| if (_default != null) |
| return _default; |
| if (_defaultStr == null) |
| return null; |
| |
| switch (_javaType) { |
| case JavaTypes.BOOLEAN: |
| case JavaTypes.BOOLEAN_OBJ: |
| _default = ("true".equals(_defaultStr)) ? Boolean.TRUE |
| : Boolean.FALSE; |
| break; |
| case JavaTypes.BYTE: |
| case JavaTypes.BYTE_OBJ: |
| _default = new Byte(_defaultStr); |
| break; |
| case JavaTypes.CHAR: |
| case JavaTypes.CHAR_OBJ: |
| _default = Character.valueOf(_defaultStr.charAt(0)); |
| break; |
| case JavaTypes.DOUBLE: |
| case JavaTypes.DOUBLE_OBJ: |
| _default = new Double(_defaultStr); |
| break; |
| case JavaTypes.FLOAT: |
| case JavaTypes.FLOAT_OBJ: |
| _default = new Float(_defaultStr); |
| break; |
| case JavaTypes.INT: |
| case JavaTypes.INT_OBJ: |
| _default = Integer.parseInt(_defaultStr); |
| break; |
| case JavaTypes.LONG: |
| case JavaTypes.LONG_OBJ: |
| _default = Long.parseLong(_defaultStr); |
| break; |
| case JavaTypes.NUMBER: |
| case JavaTypes.BIGDECIMAL: |
| _default = new BigDecimal(_defaultStr); |
| break; |
| case JavaTypes.SHORT: |
| case JavaTypes.SHORT_OBJ: |
| _default = new Short(_defaultStr); |
| break; |
| case JavaTypes.DATE: |
| _default = new java.util.Date(_defaultStr); |
| break; |
| case JavaTypes.BIGINTEGER: |
| _default = new BigInteger(_defaultStr); |
| break; |
| case JavaSQLTypes.SQL_DATE: |
| _default = Date.valueOf(_defaultStr); |
| break; |
| case JavaSQLTypes.TIMESTAMP: |
| _default = Timestamp.valueOf(_defaultStr); |
| break; |
| case JavaSQLTypes.TIME: |
| _default = Time.valueOf(_defaultStr); |
| break; |
| default: |
| _default = _defaultStr; |
| } |
| return _default; |
| } |
| |
| /** |
| * Set the default value for the column. |
| */ |
| public void setDefault(Object def) { |
| _default = def; |
| _defaultStr = (def == null) ? null : def.toString(); |
| } |
| |
| /** |
| * Return true if this is a NOT NULL column. |
| */ |
| public boolean isNotNull() { |
| return Boolean.TRUE.equals(_notNull); |
| } |
| |
| /** |
| * Set whether this is a NOT NULL column. |
| */ |
| public void setNotNull(boolean notNull) { |
| _notNull = (notNull) ? Boolean.TRUE : Boolean.FALSE; |
| } |
| |
| /** |
| * Whether the not-null property has been set. |
| */ |
| public boolean isNotNullExplicit() { |
| return _notNull != null; |
| } |
| |
| /** |
| * Sets nullability of this receiver by the given flag. |
| * @param flag one of the JDBC nullability flag namely |
| * <LI> {@link DatabaseMetaData#columnNullableUnknown} : not known if the column can be set to null value |
| * <LI> {@link DatabaseMetaData#columnNullable} : the column can be set to null value |
| * <LI> {@link DatabaseMetaData#columnNoNulls} : the column can not be set to null value |
| */ |
| public void setNullability(short flag) { |
| switch (flag) { |
| case DatabaseMetaData.columnNullableUnknown : _notNull = null; break; |
| case DatabaseMetaData.columnNullable : _notNull = false; break; |
| case DatabaseMetaData.columnNoNulls : _notNull = true; break; |
| |
| } |
| } |
| |
| /** |
| * Whether this column is auto-assigned a value on insert. |
| */ |
| public boolean isAutoAssigned() { |
| return _autoAssign; |
| } |
| |
| /** |
| * Whether this column is auto-incrementing. |
| */ |
| public void setAutoAssigned(boolean autoAssign) { |
| if (autoAssign != _autoAssign && getTable() != null) |
| getTable().changeAutoAssigned(this); |
| _autoAssign = autoAssign; |
| } |
| |
| /** |
| * Whether this column stores some form of serialized identity value for |
| * a related record. This makes the column dependent on the knowing the |
| * final identity of the relation before the column value is set. |
| */ |
| public boolean isRelationId() { |
| return _rel; |
| } |
| |
| /** |
| * Whether this column stores some form of serialized identity value for |
| * a related record. This makes the column dependent on the knowing the |
| * final identity of the relation before the column value is set. |
| */ |
| public void setRelationId(boolean rel) { |
| if (rel != _rel && getTable() != null) |
| getTable().changeRelationId(this); |
| _rel = rel; |
| } |
| |
| /** |
| * The name of the column this column joins to, if any. Used for mapping. |
| * @deprecated use getTargetIdentifier() |
| */ |
| @Deprecated |
| public String getTarget() { |
| return getTargetIdentifier().getName(); |
| } |
| |
| public DBIdentifier getTargetIdentifier() { |
| return _target == null ? DBIdentifier.NULL : _target; |
| } |
| |
| /** |
| * The name of the column this column joins to, if any. Used for mapping. |
| * @deprecated use setTargetIdentifier(DBIdentifier target) |
| */ |
| @Deprecated |
| public void setTarget(String target) { |
| setTargetIdentifier(DBIdentifier.newColumn(StringUtil.trimToNull(target))); |
| } |
| |
| public void setTargetIdentifier(DBIdentifier target) { |
| _target = target == null ? DBIdentifier.NULL : DBIdentifier.trimToNull(target); |
| } |
| |
| /** |
| * The name of the field this column joins to, if any. Used for mapping. |
| */ |
| public String getTargetField() { |
| return _targetField; |
| } |
| |
| /** |
| * The name of the field this column joins to, if any. Used for mapping. |
| */ |
| public void setTargetField(String target) { |
| if (target != null && target.length() == 0) |
| target = null; |
| _targetField = target; |
| } |
| |
| /** |
| * Flags are used for bookkeeping information. They are ignored at runtime. |
| */ |
| public boolean getFlag(int flag) { |
| return (_flags & flag) != 0; |
| } |
| |
| /** |
| * Flags are used for bookkeeping information. They are ignored at runtime. |
| */ |
| public void setFlag(int flag, boolean on) { |
| if (on) |
| _flags |= flag; |
| else |
| _flags &= ~flag; |
| } |
| |
| /** |
| * Return true if this column belongs to the table's primary key. |
| */ |
| public boolean isPrimaryKey() { |
| return _pk; |
| } |
| |
| /** |
| * Set whether this column belongs to the table's primary key. |
| */ |
| void setPrimaryKey(boolean pk) { |
| _pk = pk; |
| } |
| |
| /** |
| * Return the column's 0-based index in the owning table. |
| */ |
| public int getIndex() { |
| if (getTable() != null) |
| getTable().indexColumns(); |
| return _index; |
| } |
| |
| /** |
| * Set the column's 0-based index in the owning table. |
| */ |
| public void setIndex(int index) { |
| _index = index; |
| } |
| |
| /** |
| * Whether this column is a LOB. |
| */ |
| public boolean isLob() { |
| switch (_type) { |
| case Types.BINARY: |
| case Types.BLOB: |
| case Types.LONGVARBINARY: |
| case Types.VARBINARY: |
| case Types.CLOB: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| /** |
| * Return true if this column is compatible with the given JDBC type |
| * from {@link Types} and size. |
| */ |
| public boolean isCompatible(int type, String typeName, int size, |
| int decimals) { |
| if (type == Types.OTHER || getType() == Types.OTHER) |
| return true; |
| |
| // note that the given size is currently ignored, but may be useful |
| // to dynamically-populating subclasses |
| switch (getType()) { |
| case Types.BIT: |
| case Types.TINYINT: |
| case Types.BIGINT: |
| case Types.INTEGER: |
| case Types.NUMERIC: |
| case Types.SMALLINT: |
| case Types.DECIMAL: |
| case Types.DOUBLE: |
| case Types.FLOAT: |
| case Types.REAL: |
| switch (type) { |
| case Types.BIT: |
| case Types.TINYINT: |
| case Types.BIGINT: |
| case Types.INTEGER: |
| case Types.NUMERIC: |
| case Types.SMALLINT: |
| case Types.DECIMAL: |
| case Types.DOUBLE: |
| case Types.FLOAT: |
| case Types.REAL: |
| return true; |
| default: |
| return false; |
| } |
| case Types.BINARY: |
| case Types.BLOB: |
| case Types.LONGVARBINARY: |
| case Types.VARBINARY: |
| case Types.OTHER: |
| switch (type) { |
| case Types.BINARY: |
| case Types.BLOB: |
| case Types.LONGVARBINARY: |
| case Types.VARBINARY: |
| case Types.OTHER: |
| return true; |
| default: |
| return false; |
| } |
| case Types.CLOB: |
| case Types.CHAR: |
| case Types.LONGVARCHAR: |
| case Types.VARCHAR: |
| switch (type) { |
| case Types.CLOB: |
| case Types.CHAR: |
| case Types.LONGVARCHAR: |
| case Types.VARCHAR: |
| case Types.DATE: |
| case Types.TIME: |
| case Types.TIMESTAMP: |
| return true; |
| default: |
| return false; |
| } |
| case Types.DATE: |
| case Types.TIME: |
| case Types.TIMESTAMP: |
| switch (type) { |
| case Types.LONGVARCHAR: |
| case Types.CLOB: |
| case Types.VARCHAR: |
| case Types.DATE: |
| case Types.TIME: |
| case Types.TIMESTAMP: |
| return true; |
| default: |
| return false; |
| } |
| case 2007: // Oracle-defined opaque type code for XMLType |
| switch (type) { |
| case Types.CHAR: |
| case Types.LONGVARCHAR: |
| case Types.VARCHAR: |
| case Types.CLOB: |
| case Types.BLOB: |
| return true; |
| default: |
| return false; |
| } |
| |
| default: |
| return type == getType(); |
| } |
| } |
| |
| /** |
| * Returns the column name. |
| */ |
| @Override |
| public String toString() { |
| return getIdentifier().getName(); |
| } |
| |
| /** |
| * Useful for debugging. |
| */ |
| public String getDescription() { |
| StringBuilder buf = new StringBuilder(); |
| buf.append("Full Name: ").append(getFullName()).append("\n"); |
| buf.append("Type: ").append(Schemas.getJDBCName(getType())). |
| append("\n"); |
| buf.append("Size: ").append(getSize()).append("\n"); |
| buf.append("Default: ").append(getDefaultString()).append("\n"); |
| buf.append("Not Null: ").append(isNotNull()).append("\n"); |
| return buf.toString(); |
| } |
| |
| /** |
| * Tests compatibility. |
| */ |
| public boolean equalsColumn(DBDictionary dict, Column col) { |
| if (col == this) |
| return true; |
| if (col == null) |
| return false; |
| |
| if (!getQualifiedPath().equals(col.getQualifiedPath())) |
| return false; |
| if (!isCompatible(col.getType(), col.getTypeIdentifier().getName(), col.getSize(), |
| col.getDecimalDigits())) { |
| // do an additional lookup in case the java.sql.Types are different but |
| // they map to the same representation in the DB |
| if (dict.getTypeName(this).equals(dict.getTypeName(col))) { |
| return true; |
| } |
| return false; |
| } |
| if (getType() == Types.VARCHAR && getSize() > 0 && col.getSize() > 0 |
| && getSize() != col.getSize()) |
| return false; |
| return true; |
| } |
| |
| /** |
| * Copy information from the given column to this one. |
| */ |
| public void copy(Column from) { |
| if (from == null) |
| return; |
| if (DBIdentifier.isNull(getIdentifier())) |
| setIdentifier(from.getIdentifier()); |
| if (getType() == Types.OTHER) |
| setType(from.getType()); |
| if (DBIdentifier.isNull(getTypeIdentifier())) |
| setTypeIdentifier(from.getTypeIdentifier()); |
| if (getJavaType() == JavaTypes.OBJECT) |
| setJavaType(from.getJavaType()); |
| if (getSize() == 0) |
| setSize(from.getSize()); |
| if (getDecimalDigits() == 0) |
| setDecimalDigits(from.getDecimalDigits()); |
| if (getDefaultString() == null) |
| setDefaultString(from.getDefaultString()); |
| if (!isNotNullExplicit() && from.isNotNullExplicit()) |
| setNotNull(from.isNotNull()); |
| if (!isAutoAssigned()) |
| setAutoAssigned(from.isAutoAssigned()); |
| if (!isRelationId()) |
| setRelationId(from.isRelationId()); |
| if (!isImplicitRelation()) |
| setImplicitRelation(from.isRelationId()); |
| if (DBIdentifier.isNull(getTargetIdentifier())) |
| setTargetIdentifier(from.getTargetIdentifier()); |
| if (getTargetField() == null) |
| setTargetField(from.getTargetField()); |
| if (_flags == 0) |
| _flags = from._flags; |
| if (!isXML()) |
| setXML(from.isXML()); |
| if (!isUni1MFK()) |
| setUni1MFK(from.isUni1MFK()); |
| for (Constraint c : _constraints) { |
| addConstraint(c); |
| } |
| } |
| |
| /** |
| * Whether this column is of XML type. |
| */ |
| public boolean isXML() { |
| return _XML; |
| } |
| |
| /** |
| * Whether this column is of XML type. |
| */ |
| public void setXML(boolean xml) { |
| _XML = xml; |
| } |
| |
| public VersionStrategy getVersionStrategy() { |
| return _versionStrategy; |
| } |
| |
| public void setVersionStrategy(VersionStrategy strategy) { |
| this._versionStrategy = strategy; |
| } |
| |
| public boolean hasComment() { |
| return _comment != null && !_comment.equalsIgnoreCase(_name.toString()); |
| } |
| |
| public String getComment() { |
| return _comment; |
| } |
| |
| public void setComment(String comment) { |
| _comment = comment; |
| } |
| |
| /** |
| * Affirms if this instance represents an implicit relation. For example, a |
| * relation expressed as the value of primary key of the related class and |
| * not as object reference. |
| * |
| * @since 1.3.0 |
| */ |
| public boolean isImplicitRelation() { |
| return _implicitRelation; |
| } |
| |
| /** |
| * Sets a marker to imply a logical relation that can not have any physical |
| * manifest in the database. For example, a relation expressed as the value |
| * of primary key of the related class and not as object reference. |
| * Populated from @ForeignKey(implicit=true) annotation. |
| * The mutator can only transit from false to true but not vice versa. |
| * |
| * @since 1.3.0 |
| */ |
| public void setImplicitRelation(boolean flag) { |
| _implicitRelation |= flag; |
| } |
| |
| /** |
| * Sets a marker to indicate that this instance represents a uni-directional |
| * one to many relation using the foreign key strategy. This non-default |
| * mapping of uni-directional one-to-many is supported in JPA 2.0. |
| * |
| * @since 2.0 |
| */ |
| public boolean isUni1MFK() { |
| return _isUni1MFK; |
| } |
| |
| /** |
| * Affirms if this instance represents a uni-directional one to many relation |
| * using the foreign key strategy. This non-default mapping of uni-directional |
| * one-to-many is supported in JPA 2.0. |
| * |
| * @since 2.0 |
| */ |
| public void setUni1MFK(boolean isUni1MFK) { |
| _isUni1MFK = isUni1MFK; |
| } |
| |
| /** |
| * Adds the given constraint to this column. |
| */ |
| public void addConstraint(Constraint c) { |
| _constraints.add(c); |
| } |
| |
| /** |
| * Removes the given constraint from this column. |
| */ |
| public void removeConstraint(Constraint c) { |
| _constraints.remove(c); |
| } |
| |
| /** |
| * Affirms if this column has any constraint of given type. |
| */ |
| public boolean hasConstraint(Class<? extends Constraint> type) { |
| return !getConstraints(type).isEmpty(); |
| } |
| |
| /** |
| * Gets all constrains attached this column. |
| */ |
| public Set<Constraint> getConstraints() { |
| return _constraints; |
| } |
| |
| /** |
| * Gets all constrains of the given type attached to this column. |
| */ |
| public <T extends Constraint> Set<T> getConstraints(Class<T> type) { |
| Set<T> result = new HashSet<>(); |
| for (Constraint c : _constraints) { |
| if (c.getClass() == type) { |
| result.add((T)c); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Affirms if any unique constraint is attached to this column. |
| */ |
| public boolean isUniqueConstraint() { |
| return hasConstraint(Unique.class); |
| } |
| |
| /** |
| * Affirms if any index constraint is attached to this column. |
| */ |
| public boolean isIndex() { |
| return hasConstraint(Index.class); |
| } |
| |
| /** |
| * Affirms if any foreign key constraint is attached to this column. |
| */ |
| public boolean isForeignKey() { |
| return hasConstraint(ForeignKey.class); |
| } |
| } |