You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ddlutils-dev@db.apache.org by to...@apache.org on 2005/12/21 00:47:06 UTC
svn commit: r358148 - in
/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform:
DefaultValueHelper.java DerbyBuilder.java PlatformImplBase.java
SqlBuilder.java
Author: tomdz
Date: Tue Dec 20 15:46:57 2005
New Revision: 358148
URL: http://svn.apache.org/viewcvs?rev=358148&view=rev
Log:
Added ability for the sql builders to convert the default values to the corresponding native values
Added first usage of this to the Derby builder for column types BOOLEAN/BIT (which are mapped to SMALLINT)
Added:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DefaultValueHelper.java
Modified:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyBuilder.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/SqlBuilder.java
Added: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DefaultValueHelper.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DefaultValueHelper.java?rev=358148&view=auto
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DefaultValueHelper.java (added)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DefaultValueHelper.java Tue Dec 20 15:46:57 2005
@@ -0,0 +1,86 @@
+package org.apache.ddlutils.platform;
+
+import java.sql.Types;
+
+import org.apache.commons.beanutils.ConversionException;
+import org.apache.commons.beanutils.ConvertUtils;
+import org.apache.ddlutils.model.TypeMap;
+import org.apache.ddlutils.util.Jdbc3Utils;
+
+/**
+ * Helper class for dealing with default values, e.g. converting them to other types.
+ *
+ * @author Thomas Dudziak
+ * @version $Revision: 289996 $
+ */
+public class DefaultValueHelper
+{
+ /**
+ * Converts the given default value from the specified original to the target
+ * jdbc type.
+ *
+ * @param defaultValue The default value
+ * @param originalTypeCode The original type code
+ * @param targetTypeCode The target type code
+ * @return The converted default value
+ */
+ public Object convert(String defaultValue, int originalTypeCode, int targetTypeCode)
+ {
+ Object result = defaultValue;
+
+ if (defaultValue != null)
+ {
+ switch (originalTypeCode)
+ {
+ case Types.BIT:
+ result = convertBoolean(defaultValue, targetTypeCode);
+ break;
+ default:
+ if (Jdbc3Utils.supportsJava14JdbcTypes() &&
+ (originalTypeCode == Jdbc3Utils.determineBooleanTypeCode()))
+ {
+ result = convertBoolean(defaultValue, targetTypeCode);
+ }
+ break;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Converts a boolean default value to the given target type.
+ *
+ * @param defaultValue The default value
+ * @param targetTypeCode The target type code
+ * @return
+ */
+ private Object convertBoolean(String defaultValue, int targetTypeCode)
+ {
+ Boolean value = null;
+ Object result = null;
+
+ try
+ {
+ value = (Boolean)ConvertUtils.convert(defaultValue, Boolean.class);
+ }
+ catch (ConversionException ex)
+ {
+ return defaultValue;
+ }
+
+ if ((targetTypeCode == Types.BIT) ||
+ (Jdbc3Utils.supportsJava14JdbcTypes() && (targetTypeCode == Jdbc3Utils.determineBooleanTypeCode())))
+ {
+ result = value;
+ }
+ else if (TypeMap.isNumericType(targetTypeCode))
+ {
+ result = (value.booleanValue() ? new Integer(1) : new Integer(0));
+ }
+ else
+ {
+ result = value.toString();
+ }
+ return result;
+ }
+}
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyBuilder.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyBuilder.java?rev=358148&r1=358147&r2=358148&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyBuilder.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyBuilder.java Tue Dec 20 15:46:57 2005
@@ -17,10 +17,12 @@
*/
import java.io.IOException;
+import java.sql.Types;
import org.apache.ddlutils.PlatformInfo;
import org.apache.ddlutils.model.Column;
import org.apache.ddlutils.model.Table;
+import org.apache.ddlutils.util.Jdbc3Utils;
/**
* The SQL Builder for Derby.
@@ -38,6 +40,22 @@
public DerbyBuilder(PlatformInfo info)
{
super(info);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String getNativeDefaultValue(Column column)
+ {
+ if ((column.getTypeCode() == Types.BIT) ||
+ (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils.determineBooleanTypeCode())))
+ {
+ return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), Types.SMALLINT).toString();
+ }
+ else
+ {
+ return super.getNativeDefaultValue(column);
+ }
}
/**
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java?rev=358148&r1=358147&r2=358148&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java Tue Dec 20 15:46:57 2005
@@ -26,6 +26,7 @@
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
@@ -35,6 +36,8 @@
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.Predicate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ddlutils.DynaSqlException;
@@ -826,51 +829,54 @@
}
/**
- * {@inheritDoc}
+ * Returns all properties where the column is not non-autoincrement and for which the bean
+ * either has a value or the column hasn't got a default value, for the given dyna class.
+ *
+ * @param model The database model
+ * @param dynaClass The dyna class
+ * @param bean The bean
+ * @return The properties
*/
- public void insert(Connection connection, Database model, DynaBean dynaBean) throws DynaSqlException
+ private SqlDynaProperty[] getPropertiesForInsertion(Database model, SqlDynaClass dynaClass, final DynaBean bean)
{
- SqlDynaClass dynaClass = model.getDynaClassFor(dynaBean);
SqlDynaProperty[] properties = dynaClass.getSqlDynaProperties();
- if (properties.length == 0)
- {
- _log.warn("Cannot insert instances of type " + dynaClass + " because it has no properties");
- return;
- }
+ Collection result = CollectionUtils.select(Arrays.asList(properties), new Predicate() {
+ public boolean evaluate(Object input) {
+ SqlDynaProperty prop = (SqlDynaProperty)input;
- Column[] columns = model.findTable(dynaClass.getTableName()).getAutoIncrementColumns();
+ return !prop.getColumn().isAutoIncrement() &&
+ ((bean.get(prop.getName()) != null) || (prop.getColumn().getDefaultValue() == null));
+ }
+ });
- if (columns.length > 0)
- {
- SqlDynaProperty[] newProperties = new SqlDynaProperty[properties.length - 1];
- int newIdx = 0;
+ return (SqlDynaProperty[])result.toArray(new SqlDynaProperty[result.size()]);
+ }
- // We have to remove the auto-increment columns as some databases won't like
- // it being present in the insert command
+ /**
+ * {@inheritDoc}
+ */
+ public void insert(Connection connection, Database model, DynaBean dynaBean) throws DynaSqlException
+ {
+ SqlDynaClass dynaClass = model.getDynaClassFor(dynaBean);
+ SqlDynaProperty[] properties = getPropertiesForInsertion(model, dynaClass, dynaBean);
+ Column[] autoIncrColumns = model.findTable(dynaClass.getTableName()).getAutoIncrementColumns();
- for (int propIdx = 0; propIdx < properties.length; propIdx++)
- {
- for (int autoIncrColumnIdx = 0; autoIncrColumnIdx < columns.length; autoIncrColumnIdx++)
- {
- if (properties[propIdx].getColumn() != columns[autoIncrColumnIdx])
- {
- newProperties[newIdx++] = properties[propIdx];
- }
- }
- }
- properties = newProperties;
+ if ((properties.length == 0) && (autoIncrColumns.length == 0))
+ {
+ _log.warn("Cannot insert instances of type " + dynaClass + " because it has no usable properties");
+ return;
}
-
- String insertSql = createInsertSql(model, dynaClass, properties, null);
- String queryIdSql = columns.length > 0 ? createSelectLastInsertIdSql(model, dynaClass) : null;
- PreparedStatement statement = null;
+
+ String insertSql = createInsertSql(model, dynaClass, properties, null);
+ String queryIdSql = autoIncrColumns.length > 0 ? createSelectLastInsertIdSql(model, dynaClass) : null;
+ PreparedStatement statement = null;
if (_log.isDebugEnabled())
{
_log.debug("About to execute SQL: " + insertSql);
}
- if ((columns.length > 0) && (queryIdSql == null))
+ if ((autoIncrColumns.length > 0) && (queryIdSql == null))
{
_log.warn("The database does not support querying for auto-generated pk values");
}
@@ -921,11 +927,11 @@
lastInsertedIds.next();
- for (int idx = 0; idx < columns.length; idx++)
+ for (int idx = 0; idx < autoIncrColumns.length; idx++)
{
- Object value = lastInsertedIds.getObject(columns[idx].getName());
+ Object value = lastInsertedIds.getObject(autoIncrColumns[idx].getName());
- PropertyUtils.setProperty(dynaBean, columns[idx].getName(), value);
+ PropertyUtils.setProperty(dynaBean, autoIncrColumns[idx].getName(), value);
}
}
catch (NoSuchMethodException ex)
@@ -1003,36 +1009,13 @@
}
dynaClass = curDynaClass;
- properties = dynaClass.getSqlDynaProperties();
+ properties = getPropertiesForInsertion(model, curDynaClass, dynaBean);
if (properties.length == 0)
{
- _log.warn("Cannot insert instances of type " + dynaClass + " because it has no properties");
+ _log.warn("Cannot insert instances of type " + dynaClass + " because it has no usable properties");
continue;
}
-
- Column[] columns = model.findTable(dynaClass.getTableName()).getAutoIncrementColumns();
-
- if (columns.length > 0)
- {
- SqlDynaProperty[] newProperties = new SqlDynaProperty[properties.length - 1];
- int newIdx = 0;
-
- // We have to remove the auto-increment columns as some databases won't like
- // it being present in the insert command
-
- for (int propIdx = 0; propIdx < properties.length; propIdx++)
- {
- for (int autoIncrColumnIdx = 0; autoIncrColumnIdx < columns.length; autoIncrColumnIdx++)
- {
- if (properties[propIdx].getColumn() != columns[autoIncrColumnIdx])
- {
- newProperties[newIdx++] = properties[propIdx];
- }
- }
- }
- properties = newProperties;
- }
String insertSql = createInsertSql(model, dynaClass, properties, null);
@@ -1451,8 +1434,8 @@
*/
protected void setObject(PreparedStatement statement, int sqlIndex, DynaBean dynaBean, SqlDynaProperty property) throws SQLException
{
- int typeCode = property.getColumn().getTypeCode();
- Object value = dynaBean.get(property.getName());
+ int typeCode = property.getColumn().getTypeCode();
+ Object value = dynaBean.get(property.getName());
if (value == null)
{
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/SqlBuilder.java
URL: http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/SqlBuilder.java?rev=358148&r1=358147&r2=358148&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/SqlBuilder.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/SqlBuilder.java Tue Dec 20 15:46:57 2005
@@ -35,6 +35,7 @@
import org.apache.ddlutils.model.Index;
import org.apache.ddlutils.model.IndexColumn;
import org.apache.ddlutils.model.Table;
+import org.apache.ddlutils.model.TypeMap;
/**
* This class is a collection of Strategy methods for creating the DDL required to create and drop
@@ -83,6 +84,9 @@
/** The number formatter. */
private NumberFormat _valueNumberFormat;
+ /** Helper object for dealing with default values. */
+ private DefaultValueHelper _defaultValueHelper = new DefaultValueHelper();
+
//
// Configuration
//
@@ -127,6 +131,16 @@
_writer = writer;
}
+ /**
+ * Returns the default value helper.
+ *
+ * @return The default value helper
+ */
+ protected DefaultValueHelper getDefaultValueHelper()
+ {
+ return _defaultValueHelper;
+ }
+
/**
* Returns the string used to indent the SQL.
*
@@ -881,6 +895,77 @@
}
/**
+ * Generates the string representation of the given value.
+ *
+ * @param column The column
+ * @param value The value
+ * @return The string representation
+ */
+ protected String getValueAsString(Column column, Object value)
+ {
+ if (value == null)
+ {
+ return "NULL";
+ }
+
+ StringBuffer result = new StringBuffer();
+
+ // TODO: Handle binary types (BINARY, VARBINARY, LONGVARBINARY, BLOB)
+ switch (column.getTypeCode())
+ {
+ // Note: TIMESTAMP (java.sql.Timestamp) is properly handled by its toString method
+ case Types.DATE:
+ result.append(getPlatformInfo().getValueQuoteToken());
+ if (!(value instanceof String) && (_valueDateFormat != null))
+ {
+ // TODO: Can the format method handle java.sql.Date properly ?
+ result.append(_valueDateFormat.format(value));
+ }
+ else
+ {
+ result.append(value.toString());
+ }
+ result.append(getPlatformInfo().getValueQuoteToken());
+ break;
+ case Types.TIME:
+ result.append(getPlatformInfo().getValueQuoteToken());
+ if (!(value instanceof String) && (_valueTimeFormat != null))
+ {
+ // TODO: Can the format method handle java.sql.Date properly ?
+ result.append(_valueTimeFormat.format(value));
+ }
+ else
+ {
+ result.append(value.toString());
+ }
+ result.append(getPlatformInfo().getValueQuoteToken());
+ break;
+ case Types.REAL:
+ case Types.NUMERIC:
+ case Types.FLOAT:
+ case Types.DOUBLE:
+ case Types.DECIMAL:
+ result.append(getPlatformInfo().getValueQuoteToken());
+ if (!(value instanceof String) && (_valueNumberFormat != null))
+ {
+ result.append(_valueNumberFormat.format(value));
+ }
+ else
+ {
+ result.append(value.toString());
+ }
+ result.append(getPlatformInfo().getValueQuoteToken());
+ break;
+ default:
+ result.append(getPlatformInfo().getValueQuoteToken());
+ result.append(value.toString());
+ result.append(getPlatformInfo().getValueQuoteToken());
+ break;
+ }
+ return result.toString();
+ }
+
+ /**
* Generates the SQL for querying the id that was created in the last insertion
* operation. This is obviously only useful for pk fields that are auto-incrementing.
* A database that does not support this, will return <code>null</code>.
@@ -1028,9 +1113,7 @@
if (column.getDefaultValue() != null)
{
print(" DEFAULT ");
- print(getPlatformInfo().getValueQuoteToken());
- print(column.getDefaultValue());
- print(getPlatformInfo().getValueQuoteToken());
+ writeColumnDefaultValue(table, column);
}
if (column.isRequired())
{
@@ -1124,76 +1207,37 @@
}
/**
- * Generates the string representation of the given value.
+ * Returns the native default value for the column.
*
* @param column The column
- * @param value The value
- * @return The string representation
+ * @return The native default value
*/
- protected String getValueAsString(Column column, Object value)
+ protected String getNativeDefaultValue(Column column)
{
- if (value == null)
+ return column.getDefaultValue();
+ }
+
+ /**
+ * Prints the default value of the column.
+ *
+ * @param table The table
+ * @param column The column
+ */
+ protected void writeColumnDefaultValue(Table table, Column column) throws IOException
+ {
+ boolean shouldUseQuotes = !TypeMap.isNumericType(column.getTypeCode());
+
+ if (shouldUseQuotes)
{
- return "NULL";
+ print(getPlatformInfo().getValueQuoteToken());
}
-
- StringBuffer result = new StringBuffer();
-
- // TODO: Handle binary types (BINARY, VARBINARY, LONGVARBINARY, BLOB)
- switch (column.getTypeCode())
+ print(getNativeDefaultValue(column).toString());
+ if (shouldUseQuotes)
{
- // Note: TIMESTAMP (java.sql.Timestamp) is properly handled by its toString method
- case Types.DATE:
- result.append(getPlatformInfo().getValueQuoteToken());
- if (!(value instanceof String) && (_valueDateFormat != null))
- {
- // TODO: Can the format method handle java.sql.Date properly ?
- result.append(_valueDateFormat.format(value));
- }
- else
- {
- result.append(value.toString());
- }
- result.append(getPlatformInfo().getValueQuoteToken());
- break;
- case Types.TIME:
- result.append(getPlatformInfo().getValueQuoteToken());
- if (!(value instanceof String) && (_valueTimeFormat != null))
- {
- // TODO: Can the format method handle java.sql.Date properly ?
- result.append(_valueTimeFormat.format(value));
- }
- else
- {
- result.append(value.toString());
- }
- result.append(getPlatformInfo().getValueQuoteToken());
- break;
- case Types.REAL:
- case Types.NUMERIC:
- case Types.FLOAT:
- case Types.DOUBLE:
- case Types.DECIMAL:
- result.append(getPlatformInfo().getValueQuoteToken());
- if (!(value instanceof String) && (_valueNumberFormat != null))
- {
- result.append(_valueNumberFormat.format(value));
- }
- else
- {
- result.append(value.toString());
- }
- result.append(getPlatformInfo().getValueQuoteToken());
- break;
- default:
- result.append(getPlatformInfo().getValueQuoteToken());
- result.append(value.toString());
- result.append(getPlatformInfo().getValueQuoteToken());
- break;
+ print(getPlatformInfo().getValueQuoteToken());
}
- return result.toString();
}
-
+
/**
* Prints that the column is an auto increment column.
*