001: //$Id: Column.java 11357 2007-03-29 01:42:35Z steve.ebersole@jboss.com $
002: package org.hibernate.mapping;
003:
004: import java.io.Serializable;
005:
006: import org.hibernate.HibernateException;
007: import org.hibernate.MappingException;
008: import org.hibernate.dialect.Dialect;
009: import org.hibernate.dialect.function.SQLFunctionRegistry;
010: import org.hibernate.engine.Mapping;
011: import org.hibernate.util.StringHelper;
012:
013: /**
014: * A column of a relational database table
015: * @author Gavin King
016: */
017: public class Column implements Selectable, Serializable, Cloneable {
018:
019: public static final int DEFAULT_LENGTH = 255;
020: public static final int DEFAULT_PRECISION = 19;
021: public static final int DEFAULT_SCALE = 2;
022:
023: private int length = DEFAULT_LENGTH;
024: private int precision = DEFAULT_PRECISION;
025: private int scale = DEFAULT_SCALE;
026: private Value value;
027: private int typeIndex = 0;
028: private String name;
029: private boolean nullable = true;
030: private boolean unique = false;
031: private String sqlType;
032: private Integer sqlTypeCode;
033: private boolean quoted = false;
034: int uniqueInteger;
035: private String checkConstraint;
036: private String comment;
037: private String defaultValue;
038:
039: public Column() {
040: };
041:
042: public Column(String columnName) {
043: setName(columnName);
044: }
045:
046: public int getLength() {
047: return length;
048: }
049:
050: public void setLength(int length) {
051: this .length = length;
052: }
053:
054: public Value getValue() {
055: return value;
056: }
057:
058: public void setValue(Value value) {
059: this .value = value;
060: }
061:
062: public String getName() {
063: return name;
064: }
065:
066: public void setName(String name) {
067: if (name.charAt(0) == '`'
068: || Dialect.QUOTE.indexOf(name.charAt(0)) > -1 //TODO: deprecated, remove eventually
069: ) {
070: quoted = true;
071: this .name = name.substring(1, name.length() - 1);
072: } else {
073: this .name = name;
074: }
075: }
076:
077: /** returns quoted name as it would be in the mapping file. */
078: public String getQuotedName() {
079: return quoted ? "`" + name + "`" : name;
080: }
081:
082: public String getQuotedName(Dialect d) {
083: return quoted ? d.openQuote() + name + d.closeQuote() : name;
084: }
085:
086: /**
087: * For any column name, generate an alias that is unique
088: * to that column name, and also 10 characters or less
089: * in length.
090: */
091: public String getAlias(Dialect dialect) {
092: String alias = name;
093: String unique = Integer.toString(uniqueInteger) + '_';
094: int lastLetter = StringHelper.lastIndexOfLetter(name);
095: if (lastLetter == -1) {
096: alias = "column";
097: } else if (lastLetter < name.length() - 1) {
098: alias = name.substring(0, lastLetter + 1);
099: }
100: if (alias.length() > dialect.getMaxAliasLength()) {
101: alias = alias.substring(0, dialect.getMaxAliasLength()
102: - unique.length());
103: }
104: boolean useRawName = name.equals(alias) && !quoted
105: && !name.toLowerCase().equals("rowid");
106: if (useRawName) {
107: return alias;
108: } else {
109: return alias + unique;
110: }
111: }
112:
113: /**
114: * Generate a column alias that is unique across multiple tables
115: */
116: public String getAlias(Dialect dialect, Table table) {
117: return getAlias(dialect) + table.getUniqueInteger() + '_';
118: }
119:
120: public boolean isNullable() {
121: return nullable;
122: }
123:
124: public void setNullable(boolean nullable) {
125: this .nullable = nullable;
126: }
127:
128: public int getTypeIndex() {
129: return typeIndex;
130: }
131:
132: public void setTypeIndex(int typeIndex) {
133: this .typeIndex = typeIndex;
134: }
135:
136: public int getSqlTypeCode(Mapping mapping) throws MappingException {
137: org.hibernate.type.Type type = getValue().getType();
138: try {
139: int sqlTypeCode = type.sqlTypes(mapping)[getTypeIndex()];
140: if (getSqlTypeCode() != null
141: && getSqlTypeCode().intValue() != sqlTypeCode) {
142: throw new MappingException(
143: "SQLType code's does not match. mapped as "
144: + sqlTypeCode + " but is "
145: + getSqlTypeCode());
146: }
147: return sqlTypeCode;
148: } catch (Exception e) {
149: throw new MappingException(
150: "Could not determine type for column " + name
151: + " of type " + type.getClass().getName()
152: + ": " + e.getClass().getName(), e);
153: }
154: }
155:
156: /**
157: * Returns the underlying columns sqltypecode.
158: * If null, it is because the sqltype code is unknown.
159: *
160: * Use #getSqlTypeCode(Mapping) to retreive the sqltypecode used
161: * for the columns associated Value/Type.
162: *
163: * @return sqltypecode if it is set, otherwise null.
164: */
165: public Integer getSqlTypeCode() {
166: return sqlTypeCode;
167: }
168:
169: public void setSqlTypeCode(Integer typecode) {
170: sqlTypeCode = typecode;
171: }
172:
173: public boolean isUnique() {
174: return unique;
175: }
176:
177: public String getSqlType(Dialect dialect, Mapping mapping)
178: throws HibernateException {
179: return sqlType == null ? dialect.getTypeName(
180: getSqlTypeCode(mapping), getLength(), getPrecision(),
181: getScale()) : sqlType;
182: }
183:
184: public boolean equals(Object object) {
185: return object instanceof Column && equals((Column) object);
186: }
187:
188: public boolean equals(Column column) {
189: if (null == column)
190: return false;
191: if (this == column)
192: return true;
193:
194: return isQuoted() ? name.equals(column.name) : name
195: .equalsIgnoreCase(column.name);
196: }
197:
198: //used also for generation of FK names!
199: public int hashCode() {
200: return isQuoted() ? name.hashCode() : name.toLowerCase()
201: .hashCode();
202: }
203:
204: public String getSqlType() {
205: return sqlType;
206: }
207:
208: public void setSqlType(String sqlType) {
209: this .sqlType = sqlType;
210: }
211:
212: public void setUnique(boolean unique) {
213: this .unique = unique;
214: }
215:
216: public boolean isQuoted() {
217: return quoted;
218: }
219:
220: public String toString() {
221: return getClass().getName() + '(' + getName() + ')';
222: }
223:
224: public String getCheckConstraint() {
225: return checkConstraint;
226: }
227:
228: public void setCheckConstraint(String checkConstraint) {
229: this .checkConstraint = checkConstraint;
230: }
231:
232: public boolean hasCheckConstraint() {
233: return checkConstraint != null;
234: }
235:
236: public String getTemplate(Dialect dialect,
237: SQLFunctionRegistry functionRegistry) {
238: return getQuotedName(dialect);
239: }
240:
241: public boolean isFormula() {
242: return false;
243: }
244:
245: public String getText(Dialect d) {
246: return getQuotedName(d);
247: }
248:
249: public String getText() {
250: return getName();
251: }
252:
253: public int getPrecision() {
254: return precision;
255: }
256:
257: public void setPrecision(int scale) {
258: this .precision = scale;
259: }
260:
261: public int getScale() {
262: return scale;
263: }
264:
265: public void setScale(int scale) {
266: this .scale = scale;
267: }
268:
269: public String getComment() {
270: return comment;
271: }
272:
273: public void setComment(String comment) {
274: this .comment = comment;
275: }
276:
277: public String getDefaultValue() {
278: return defaultValue;
279: }
280:
281: public void setDefaultValue(String defaultValue) {
282: this .defaultValue = defaultValue;
283: }
284:
285: public String getCanonicalName() {
286: return quoted ? name : name.toLowerCase();
287: }
288:
289: /**
290: * Shallow copy, the value is not copied
291: */
292: protected Object clone() {
293: Column copy = new Column();
294: copy.setLength(length);
295: copy.setScale(scale);
296: copy.setValue(value);
297: copy.setTypeIndex(typeIndex);
298: copy.setName(getQuotedName());
299: copy.setNullable(nullable);
300: copy.setPrecision(precision);
301: copy.setUnique(unique);
302: copy.setSqlType(sqlType);
303: copy.setSqlTypeCode(sqlTypeCode);
304: copy.uniqueInteger = uniqueInteger; //usually useless
305: copy.setCheckConstraint(checkConstraint);
306: copy.setComment(comment);
307: copy.setDefaultValue(defaultValue);
308: return copy;
309: }
310:
311: }
|