/* * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Florent Guillaume */ package org.eclipse.ecr.core.storage.sql.jdbc.db; import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import org.eclipse.ecr.core.storage.sql.ColumnType; import org.eclipse.ecr.core.storage.sql.jdbc.dialect.Dialect; import org.eclipse.ecr.core.storage.sql.jdbc.dialect.Dialect.JDBCInfo; /** * An SQL {@code column}. * * @author Florent Guillaume */ public class Column implements Serializable { private static final long serialVersionUID = 1L; protected final Table table; protected final Dialect dialect; protected final String physicalName; private final String quotedName; private final String freeVariableSetter; /** The abstract type. */ private final ColumnType type; /** * The JDBC {@link java.sql.Types} type. Used for: * * - comparison with database introspected type * * - switch() to get from result set or set to prepared statement * * - setNull to prepared statement */ private int jdbcType; /** The JDBC type string. */ private final String jdbcTypeString; private final String key; private boolean identity; private boolean primary; private boolean nullable = true; private String defaultValue; /** For foreign key reference. */ private Table foreignTable; private String foreignKey; /** * Creates a new column with the given name and type. * * @param table the column's table * @param physicalName the column physical name * @param type the column's type * @param key the associated field name */ public Column(Table table, String physicalName, ColumnType type, String key) { this.table = table; dialect = table.getDialect(); this.physicalName = physicalName; this.type = type; JDBCInfo jdbcInfo = dialect.getJDBCTypeAndString(type); jdbcType = jdbcInfo.jdbcType; jdbcTypeString = jdbcInfo.string; this.key = key; quotedName = dialect.openQuote() + physicalName + dialect.closeQuote(); freeVariableSetter = dialect.getFreeVariableSetterForType(type); } /** * Creates a column from an existing column and an aliased table. */ public Column(Column column, Table table) { this(table, column.physicalName, column.type, column.key); } public Table getTable() { return table; } public String getPhysicalName() { return physicalName; } public String getQuotedName() { return quotedName; } public String getFullQuotedName() { return table.getQuotedName() + '.' + quotedName; } public int getJdbcType() { return jdbcType; } public ColumnType getType() { return type; } public String getFreeVariableSetter() { return freeVariableSetter; } public boolean isOpaque() { return type == ColumnType.FTINDEXED || type == ColumnType.FTSTORED; } public boolean setJdbcType(int actual, String actualName, int actualSize) { int expected = jdbcType; if (actual == expected) { return true; } if (dialect.isAllowedConversion(expected, actual, actualName, actualSize)) { return true; } return false; } public String getKey() { return key; } public void setIdentity(boolean identity) { this.identity = identity; } public boolean isIdentity() { return identity; } public void setPrimary(boolean primary) { this.primary = primary; } public boolean isPrimary() { return primary; } public void setNullable(boolean nullable) { this.nullable = nullable; } public boolean isNullable() { return nullable; } public String getDefaultValue() { return defaultValue; } public void setDefaultValue(String defaultValue) { this.defaultValue = defaultValue; } public void setReferences(Table foreignTable, String foreignKey) { this.foreignTable = foreignTable; this.foreignKey = foreignKey; } public Table getForeignTable() { return foreignTable; } public String getForeignKey() { return foreignKey; } public String getSqlTypeString() { return jdbcTypeString; } public void setToPreparedStatement(PreparedStatement ps, int index, Serializable value) throws SQLException { if (value == null) { ps.setNull(index, jdbcType); return; } if (jdbcType == Types.ARRAY && !(value instanceof String[])) { throw new SQLException("Expected String[] instead of: " + value); } dialect.setToPreparedStatement(ps, index, value, this); } public Serializable getFromResultSet(ResultSet rs, int index) throws SQLException { Serializable result = dialect.getFromResultSet(rs, index, this); if (rs.wasNull()) { result = null; } return result; } @Override public String toString() { return getClass().getSimpleName() + '(' + physicalName + ')'; } }