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);
+ }
+
+ /**
+ * [EMAIL PROTECTED]
+ */
+ 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 @@
}
/**
- * [EMAIL PROTECTED]
+ * 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
+ /**
+ * [EMAIL PROTECTED]
+ */
+ 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.
*