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 2006/12/15 08:30:53 UTC
svn commit: r487473 - in /db/ddlutils/trunk/src: java/org/apache/ddlutils/
java/org/apache/ddlutils/io/ java/org/apache/ddlutils/platform/
java/org/apache/ddlutils/task/ test/org/apache/ddlutils/
test/org/apache/ddlutils/io/
Author: tomdz
Date: Thu Dec 14 23:30:52 2006
New Revision: 487473
URL: http://svn.apache.org/viewvc?view=rev&rev=487473
Log:
Added convenience class to read and write data from/to the database
Added ability to turn identity override on/off
Fixed bug in jdbc model reader which did not called initialize
Added tests for reading and writing data via XML
Added:
db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DatabaseDataIO.java
db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestMisc.java
Modified:
db/ddlutils/trunk/src/java/org/apache/ddlutils/Platform.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataReader.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataSink.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataToDatabaseSink.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/io/Identity.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/task/ConvertingDatabaseCommand.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToDatabaseCommand.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToFileCommand.java
db/ddlutils/trunk/src/test/org/apache/ddlutils/RunAllTests.java
db/ddlutils/trunk/src/test/org/apache/ddlutils/TestDatabaseWriterBase.java
db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDataReaderAndWriter.java
db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatatypes.java
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/Platform.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/Platform.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/Platform.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/Platform.java Thu Dec 14 23:30:52 2006
@@ -164,6 +164,26 @@
public void setSqlCommentsOn(boolean sqlCommentsOn);
/**
+ * Determines whether SQL insert statements can specify values for identity columns.
+ * This setting is only relevant if the database supports it
+ * ({@link PlatformInfo#isIdentityOverrideAllowed()). If this is off, then the
+ * <code>insert</code> methods will ignore values for identity columns.
+ *
+ * @return <code>true</code> if identity override is enabled (the default)
+ */
+ public boolean isIdentityOverrideOn();
+
+ /**
+ * Specifies whether SQL insert statements can specify values for identity columns.
+ * This setting is only relevant if the database supports it
+ * ({@link PlatformInfo#isIdentityOverrideAllowed()). If this is off, then the
+ * <code>insert</code> methods will ignore values for identity columns.
+ *
+ * @param identityOverrideOn <code>true</code> if identity override is enabled (the default)
+ */
+ public void setIdentityOverrideOn(boolean identityOverrideOn);
+
+ /**
* Determines whether foreign keys of a table read from a live database
* are alphabetically sorted.
*
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataReader.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataReader.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataReader.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataReader.java Thu Dec 14 23:30:52 2006
@@ -24,10 +24,11 @@
import org.apache.ddlutils.model.Column;
import org.apache.ddlutils.model.Database;
import org.apache.ddlutils.model.Table;
-import org.xml.sax.SAXException;
/**
- * Reads data XML into dyna beans matching a specified database model.
+ * Reads data XML into dyna beans matching a specified database model. Note that
+ * the data sink won't be started or ended by the data reader, this has to be done
+ * in the code that uses the data reader.
*
* @version $Revision: 289996 $
*/
@@ -156,23 +157,5 @@
_needsConfiguration = false;
}
super.configure();
- }
-
- /**
- * {@inheritDoc}
- */
- public void endDocument() throws SAXException
- {
- super.endDocument();
- _sink.end();
- }
-
- /**
- * {@inheritDoc}
- */
- public void startDocument() throws SAXException
- {
- _sink.start();
- super.startDocument();
}
}
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataSink.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataSink.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataSink.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataSink.java Thu Dec 14 23:30:52 2006
@@ -43,5 +43,5 @@
/**
* Notifies the sink that all beans have been added.
*/
- public void end() throws DataSinkException;
+ public void end() throws DataSinkException;
}
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataToDatabaseSink.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataToDatabaseSink.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataToDatabaseSink.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DataToDatabaseSink.java Thu Dec 14 23:30:52 2006
@@ -66,8 +66,10 @@
private ArrayList _batchQueue = new ArrayList();
/** The number of beans to insert in one batch. */
private int _batchSize = 1024;
- /** Stores the already-processed identities per table name. */
- private HashMap _processedIdentities = new HashMap();
+ /** Stores the tables that are target of a foreign key. */
+ private HashSet _fkTables = new HashSet();
+ /** Maps original to processed identities. */
+ private HashMap _identityMap = new HashMap();
/** Stores the objects that are waiting for other objects to be inserted. */
private ArrayList _waitingObjects = new ArrayList();
@@ -196,9 +198,7 @@
*/
public void start() throws DataSinkException
{
- // we're determining all tables referenced by foreignkeys, and initialize the
- // lists of already-processed identities for these tables
- _processedIdentities.clear();
+ _fkTables.clear();
_waitingObjects.clear();
if (_ensureFkOrder)
{
@@ -210,10 +210,7 @@
{
ForeignKey curFk = table.getForeignKey(fkIdx);
- if (!_processedIdentities.containsKey(curFk.getForeignTableName()))
- {
- _processedIdentities.put(curFk.getForeignTableName(), new HashSet());
- }
+ _fkTables.add(curFk.getForeignTable());
}
}
}
@@ -245,9 +242,13 @@
if (fkIdentity != null)
{
- HashSet identitiesForTable = (HashSet)_processedIdentities.get(fk.getForeignTableName());
+ Identity processedIdentity = (Identity)_identityMap.get(fkIdentity);
- if (!identitiesForTable.contains(fkIdentity))
+ if (processedIdentity != null)
+ {
+ updateFKColumns(bean, fkIdentity.getForeignKeyName(), processedIdentity);
+ }
+ else
{
waitingObj.addPendingFK(fkIdentity);
}
@@ -258,6 +259,7 @@
if (_log.isDebugEnabled())
{
StringBuffer msg = new StringBuffer();
+
msg.append("Defering insertion of bean ");
msg.append(buildIdentityFromPKs(table, bean).toString());
msg.append(" because it is waiting for:");
@@ -272,18 +274,21 @@
return;
}
}
+
+ Identity origIdentity = buildIdentityFromPKs(table, bean);
+
insertBeanIntoDatabase(table, bean);
- if (_ensureFkOrder && _processedIdentities.containsKey(table.getName()))
+
+ if (_ensureFkOrder && _fkTables.contains(table))
{
- Identity identity = buildIdentityFromPKs(table, bean);
- HashSet identitiesForTable = (HashSet)_processedIdentities.get(table.getName());
- ArrayList finishedObjs = new ArrayList();
+ Identity newIdentity = buildIdentityFromPKs(table, bean);
+ ArrayList finishedObjs = new ArrayList();
- identitiesForTable.add(identity);
+ _identityMap.put(origIdentity, newIdentity);
for (Iterator waitingObjIt = _waitingObjects.iterator(); waitingObjIt.hasNext();)
{
WaitingObject waitingObj = (WaitingObject)waitingObjIt.next();
- Identity fkIdentity = waitingObj.removePendingFK(identity);
+ Identity fkIdentity = waitingObj.removePendingFK(origIdentity);
if (!waitingObj.hasPendingFKs())
{
@@ -291,7 +296,7 @@
// the object was only waiting for this one, so store it now
// prior to that we also update the fk fields in case one of the pk
// columns of the target object is auto-incremented by the database
- updateFKColumns(waitingObj.getObject(), bean, fkIdentity.getForeignKeyName());
+ updateFKColumns(waitingObj.getObject(), fkIdentity.getForeignKeyName(), newIdentity);
// we defer handling of the finished objects to avoid concurrent modification exceptions
finishedObjs.add(waitingObj.getObject());
}
@@ -453,12 +458,12 @@
*/
private Identity buildIdentityFromPKs(Table table, DynaBean bean)
{
- Identity identity = new Identity(table.getName());
+ Identity identity = new Identity(table);
Column[] pkColumns = table.getPrimaryKeyColumns();
for (int idx = 0; idx < pkColumns.length; idx++)
{
- identity.setIdentityColumn(pkColumns[idx].getName(), bean.get(pkColumns[idx].getName()));
+ identity.setColumnValue(pkColumns[idx].getName(), bean.get(pkColumns[idx].getName()));
}
return identity;
}
@@ -474,7 +479,7 @@
*/
private Identity buildIdentityFromFK(Table owningTable, ForeignKey fk, DynaBean bean)
{
- Identity identity = new Identity(fk.getForeignTableName(), getFKName(owningTable, fk));
+ Identity identity = new Identity(fk.getForeignTable(), getFKName(owningTable, fk));
for (int idx = 0; idx < fk.getReferenceCount(); idx++)
{
@@ -485,23 +490,23 @@
{
return null;
}
- identity.setIdentityColumn(reference.getForeignColumnName(), value);
+ identity.setColumnValue(reference.getForeignColumnName(), value);
}
return identity;
}
/**
- * Updates the values of the columns constituting the foreign key between the two given beans to
- * the current values of the primary key columns of the referenced bean.
+ * Updates the values of the columns constituting the indicated foreign key with the values
+ * of the given identity.
*
- * @param referencingBean The referencing bean whose foreign key columns shall be updated
- * @param referencedBean The referenced bean whose primary key column values will be used
- * @param fkName The name of the foreign key
+ * @param bean The bean whose columns shall be updated
+ * @param fkName The name of the foreign key
+ * @param identity The target identity
*/
- private void updateFKColumns(DynaBean referencingBean, DynaBean referencedBean, String fkName)
+ private void updateFKColumns(DynaBean bean, String fkName, Identity identity)
{
- Table sourceTable = ((SqlDynaClass)referencingBean.getDynaClass()).getTable();
- Table targetTable = ((SqlDynaClass)referencedBean.getDynaClass()).getTable();
+ Table sourceTable = ((SqlDynaClass)bean.getDynaClass()).getTable();
+ Table targetTable = identity.getTable();
ForeignKey fk = null;
for (int idx = 0; idx < sourceTable.getForeignKeyCount(); idx++)
@@ -522,10 +527,10 @@
for (int idx = 0; idx < fk.getReferenceCount(); idx++)
{
Reference curRef = fk.getReference(idx);
- Column sourceColumn = sourceTable.findColumn(curRef.getLocalColumnName());
- Column targetColumn = targetTable.findColumn(curRef.getForeignColumnName());
+ Column sourceColumn = curRef.getLocalColumn();
+ Column targetColumn = curRef.getForeignColumn();
- referencingBean.set(sourceColumn.getName(), referencedBean.get(targetColumn.getName()));
+ bean.set(sourceColumn.getName(), identity.getColumnValue(targetColumn.getName()));
}
}
}
Added: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DatabaseDataIO.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DatabaseDataIO.java?view=auto&rev=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DatabaseDataIO.java (added)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/DatabaseDataIO.java Thu Dec 14 23:30:52 2006
@@ -0,0 +1,621 @@
+package org.apache.ddlutils.io;
+
+/*
+ * 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.
+ */
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.ddlutils.DdlUtilsException;
+import org.apache.ddlutils.Platform;
+import org.apache.ddlutils.model.Column;
+import org.apache.ddlutils.model.Database;
+import org.apache.ddlutils.model.Table;
+
+/**
+ * Provides basic live database data <-> XML functionality.
+ *
+ * @version $Revision: $
+ */
+public class DatabaseDataIO
+{
+ /** The converters to use for converting between data and its XML representation. */
+ private ArrayList _converters = new ArrayList();
+ /** Whether we should continue when an error was detected. */
+ private boolean _failOnError = true;
+ /** Whether foreign key order shall be followed when inserting data into the database. */
+ private boolean _ensureFKOrder = true;
+ /** Whether we should use batch mode. */
+ private boolean _useBatchMode;
+ /** The maximum number of objects to insert in one batch. */
+ private Integer _batchSize;
+
+ /**
+ * Registers a converter.
+ *
+ * @param converterRegistration The registration info
+ */
+ public void registerConverter(DataConverterRegistration converterRegistration)
+ {
+ _converters.add(converterRegistration);
+ }
+
+ /**
+ * Determines whether data io is stopped when an error happens.
+ *
+ * @return Whether io is stopped when an error was detected (true by default)
+ */
+ public boolean isFailOnError()
+ {
+ return _failOnError;
+ }
+
+ /**
+ * Specifies whether data io shall be stopped when an error happens.
+ *
+ * @param failOnError Whether io should stop when an error was detected
+ */
+ public void setFailOnError(boolean failOnError)
+ {
+ _failOnError = failOnError;
+ }
+
+ /**
+ * Determines whether batch mode is used for inserting data into the database.
+ *
+ * @return <code>true</code> if batch mode is used
+ */
+ public boolean getUseBatchMode()
+ {
+ return _useBatchMode;
+ }
+
+ /**
+ * Specifies whether batch mode should be used for inserting data into the database.
+ *
+ * @param useBatchMode <code>true</code> if batch mode shall be used
+ */
+ public void setUseBatchMode(boolean useBatchMode)
+ {
+ _useBatchMode = useBatchMode;
+ }
+
+ /**
+ * Returns the batch size override.
+ *
+ * @return The batch size if different from the default, <code>null</code> otherwise
+ */
+ public Integer getBatchSize()
+ {
+ return _batchSize;
+ }
+
+ /**
+ * Sets the batch size to be used by this object.
+ *
+ * @param batchSize The batch size if different from the default, or <code>null</code> if
+ * the default shall be used
+ */
+ public void setBatchSize(Integer batchSize)
+ {
+ _batchSize = batchSize;
+ }
+
+ /**
+ * Determines whether the sink delays the insertion of beans so that the beans referenced by it
+ * via foreignkeys are already inserted into the database.
+ *
+ * @return <code>true</code> if beans are inserted after its foreignkey-references
+ */
+ public boolean isEnsureFKOrder()
+ {
+ return _ensureFKOrder;
+ }
+
+ /**
+ * Specifies whether the sink shall delay the insertion of beans so that the beans referenced by it
+ * via foreignkeys are already inserted into the database.<br/>
+ * Note that you should careful with setting <code>haltOnErrors</code> to false as this might
+ * result in beans not inserted at all. The sink will then throw an appropriate exception at the end
+ * of the insertion process (method {@link #end()}).
+ *
+ * @param ensureFkOrder <code>true</code> if beans shall be inserted after its foreignkey-references
+ */
+ public void setEnsureFKOrder(boolean ensureFKOrder)
+ {
+ _ensureFKOrder = ensureFKOrder;
+ }
+
+ /**
+ * Registers the converters at the given configuration.
+ *
+ * @param converterConf The converter configuration
+ */
+ private void registerConverters(ConverterConfiguration converterConf) throws DdlUtilsException
+ {
+ for (Iterator it = _converters.iterator(); it.hasNext();)
+ {
+ DataConverterRegistration registrationInfo = (DataConverterRegistration)it.next();
+
+ if (registrationInfo.getTypeCode() != Integer.MIN_VALUE)
+ {
+ converterConf.registerConverter(registrationInfo.getTypeCode(),
+ registrationInfo.getConverter());
+ }
+ else
+ {
+ if ((registrationInfo.getTable() == null) || (registrationInfo.getColumn() == null))
+ {
+ throw new DdlUtilsException("Please specify either the jdbc type or a table/column pair for which the converter shall be defined");
+ }
+ converterConf.registerConverter(registrationInfo.getTable(),
+ registrationInfo.getColumn(),
+ registrationInfo.getConverter());
+ }
+ }
+ }
+
+ /**
+ * Returns a data writer instance configured to write to the indicated file
+ * in the specified encoding.
+ *
+ * @param path The path to the output XML data file
+ * @param xmlEncoding The encoding to use for writing the XML
+ * @return The writer
+ */
+ public DataWriter getConfiguredDataWriter(String path, String xmlEncoding) throws DdlUtilsException
+ {
+ try
+ {
+ DataWriter writer = new DataWriter(new FileOutputStream(path), xmlEncoding);
+
+ registerConverters(writer.getConverterConfiguration());
+ return writer;
+ }
+ catch (IOException ex)
+ {
+ throw new DdlUtilsException(ex);
+ }
+ }
+
+ /**
+ * Returns a data writer instance configured to write to the given output stream
+ * in the specified encoding.
+ *
+ * @param output The output stream
+ * @param xmlEncoding The encoding to use for writing the XML
+ * @return The writer
+ */
+ public DataWriter getConfiguredDataWriter(OutputStream output, String xmlEncoding) throws DdlUtilsException
+ {
+ DataWriter writer = new DataWriter(output, xmlEncoding);
+
+ registerConverters(writer.getConverterConfiguration());
+ return writer;
+ }
+
+ /**
+ * Returns a data writer instance configured to write to the given output writer
+ * in the specified encoding.
+ *
+ * @param output The output writer; needs to be configured with the specified encoding
+ * @param xmlEncoding The encoding to use for writing the XML
+ * @return The writer
+ */
+ public DataWriter getConfiguredDataWriter(Writer output, String xmlEncoding) throws DdlUtilsException
+ {
+ DataWriter writer = new DataWriter(output, xmlEncoding);
+
+ registerConverters(writer.getConverterConfiguration());
+ return writer;
+ }
+
+ /**
+ * Writes the data contained in the database to which the given platform is connected, as XML
+ * to the given output stream (which won't be closed by this method).
+ *
+ * @param platform The platform; needs to be connected to a live database
+ * @param path The path of the output file
+ * @param xmlEncoding The encoding to use for the XML
+ */
+ public void writeDataToXML(Platform platform, String path, String xmlEncoding) throws DdlUtilsException
+ {
+ writeDataToXML(platform, getConfiguredDataWriter(path, xmlEncoding));
+ }
+
+ /**
+ * Writes the data contained in the database to which the given platform is connected, as XML
+ * to the given output stream (which won't be closed by this method).
+ *
+ * @param platform The platform; needs to be connected to a live database
+ * @param model The model for which to retrieve and write the data
+ * @param path The path of the output file
+ * @param xmlEncoding The encoding to use for the XML
+ */
+ public void writeDataToXML(Platform platform, Database model, String path, String xmlEncoding)
+ {
+ writeDataToXML(platform, model, getConfiguredDataWriter(path, xmlEncoding));
+ }
+
+ /**
+ * Writes the data contained in the database to which the given platform is connected, as XML
+ * to the given output stream (which won't be closed by this method).
+ *
+ * @param platform The platform; needs to be connected to a live database
+ * @param output The output stream
+ * @param xmlEncoding The encoding to use for the XML
+ */
+ public void writeDataToXML(Platform platform, OutputStream output, String xmlEncoding)
+ {
+ writeDataToXML(platform, getConfiguredDataWriter(output, xmlEncoding));
+ }
+
+ /**
+ * Writes the data contained in the database to which the given platform is connected, as XML
+ * to the given output stream (which won't be closed by this method).
+ *
+ * @param platform The platform; needs to be connected to a live database
+ * @param model The model for which to retrieve and write the data
+ * @param output The output stream
+ * @param xmlEncoding The encoding to use for the XML
+ */
+ public void writeDataToXML(Platform platform, Database model, OutputStream output, String xmlEncoding)
+ {
+ writeDataToXML(platform, model, getConfiguredDataWriter(output, xmlEncoding));
+ }
+
+ /**
+ * Writes the data contained in the database to which the given platform is connected, as XML
+ * to the given output writer (which won't be closed by this method).
+ *
+ * @param platform The platform; needs to be connected to a live database
+ * @param output The output writer (which needs to be openend with the specified encoding)
+ * @param xmlEncoding The encoding to use for the XML
+ */
+ public void writeDataToXML(Platform platform, Writer output, String xmlEncoding)
+ {
+ writeDataToXML(platform, getConfiguredDataWriter(output, xmlEncoding));
+ }
+
+ /**
+ * Writes the data contained in the database to which the given platform is connected, as XML
+ * to the given output writer (which won't be closed by this method).
+ *
+ * @param platform The platform; needs to be connected to a live database
+ * @param model The model for which to retrieve and write the data
+ * @param output The output writer (which needs to be openend with the specified encoding)
+ * @param xmlEncoding The encoding to use for the XML
+ */
+ public void writeDataToXML(Platform platform, Database model, Writer output, String xmlEncoding)
+ {
+ writeDataToXML(platform, model, getConfiguredDataWriter(output, xmlEncoding));
+ }
+
+ /**
+ * Writes the data contained in the database to which the given platform is connected, as XML
+ * to the given data writer.
+ *
+ * @param platform The platform; needs to be connected to a live database
+ * @param writer The data writer
+ */
+ public void writeDataToXML(Platform platform, DataWriter writer)
+ {
+ writeDataToXML(platform, platform.readModelFromDatabase("unnamed"), writer);
+ }
+
+ /**
+ * Writes the data contained in the database to which the given platform is connected, as XML
+ * to the given data writer.
+ *
+ * @param platform The platform; needs to be connected to a live database
+ * @param model The model for which to retrieve and write the data
+ * @param writer The data writer
+ */
+ public void writeDataToXML(Platform platform, Database model, DataWriter writer)
+ {
+ Table[] tables = new Table[1];
+
+ registerConverters(writer.getConverterConfiguration());
+
+ // TODO: An advanced algorithm could be employed here that writes objects
+ // related by foreign keys, in the correct order
+ StringBuffer query = new StringBuffer();
+
+ writer.writeDocumentStart();
+ for (int tableIdx = 0; tableIdx < model.getTableCount(); tableIdx++)
+ {
+ tables[0] = (Table)model.getTable(tableIdx);
+ query.setLength(0);
+ query.append("SELECT ");
+
+ Column[] columns = tables[0].getColumns();
+
+ for (int columnIdx = 0; columnIdx < columns.length; columnIdx++)
+ {
+ if (columnIdx > 0)
+ {
+ query.append(",");
+ }
+ if (platform.isDelimitedIdentifierModeOn())
+ {
+ query.append(platform.getPlatformInfo().getDelimiterToken());
+ }
+ query.append(columns[columnIdx].getName());
+ if (platform.isDelimitedIdentifierModeOn())
+ {
+ query.append(platform.getPlatformInfo().getDelimiterToken());
+ }
+ }
+ query.append(" FROM ");
+ if (platform.isDelimitedIdentifierModeOn())
+ {
+ query.append(platform.getPlatformInfo().getDelimiterToken());
+ }
+ query.append(tables[0].getName());
+ if (platform.isDelimitedIdentifierModeOn())
+ {
+ query.append(platform.getPlatformInfo().getDelimiterToken());
+ }
+
+ writer.write(platform.query(model, query.toString(), tables));
+ }
+ writer.writeDocumentEnd();
+ }
+
+ /**
+ * Returns a data reader instance configured for the given platform (which needs to
+ * be connected to a live database) and model.
+ *
+ * @param platform The database
+ * @param model The model
+ * @return The data reader
+ */
+ public DataReader getConfiguredDataReader(Platform platform, Database model) throws DdlUtilsException
+ {
+ DataToDatabaseSink sink = new DataToDatabaseSink(platform, model);
+ DataReader reader = new DataReader();
+
+ sink.setHaltOnErrors(_failOnError);
+ sink.setEnsureForeignKeyOrder(_ensureFKOrder);
+ sink.setUseBatchMode(_useBatchMode);
+ if (_batchSize != null)
+ {
+ sink.setBatchSize(_batchSize.intValue());
+ }
+
+ reader.setModel(model);
+ reader.setSink(sink);
+ registerConverters(reader.getConverterConfiguration());
+ return reader;
+ }
+
+ /**
+ * Reads the data from the specified files and writes it to the database to which the given
+ * platform is connected.
+ *
+ * @param platform The platform, must be connected to a live database
+ * @param files The XML data files
+ */
+ public void writeDataToDatabase(Platform platform, String[] files) throws DdlUtilsException
+ {
+ writeDataToDatabase(platform, platform.readModelFromDatabase("unnamed"), files);
+ }
+
+ /**
+ * Reads the data from the given input streams and writes it to the database to which the given
+ * platform is connected.
+ *
+ * @param platform The platform, must be connected to a live database
+ * @param input The input streams for the XML data
+ */
+ public void writeDataToDatabase(Platform platform, InputStream[] inputs) throws DdlUtilsException
+ {
+ writeDataToDatabase(platform, platform.readModelFromDatabase("unnamed"), inputs);
+ }
+
+ /**
+ * Reads the data from the given input readers and writes it to the database to which the given
+ * platform is connected.
+ *
+ * @param platform The platform, must be connected to a live database
+ * @param input The input readers for the XML data
+ */
+ public void writeDataToDatabase(Platform platform, Reader[] inputs) throws DdlUtilsException
+ {
+ writeDataToDatabase(platform, platform.readModelFromDatabase("unnamed"), inputs);
+ }
+
+ /**
+ * Reads the data from the indicated files and writes it to the database to which the given
+ * platform is connected. Only data that matches the given model will be written.
+ *
+ * @param platform The platform, must be connected to a live database
+ * @param model The model to which to constrain the written data
+ * @param files The XML data files
+ */
+ public void writeDataToDatabase(Platform platform, Database model, String[] files) throws DdlUtilsException
+ {
+ DataReader dataReader = getConfiguredDataReader(platform, model);
+
+ dataReader.getSink().start();
+ for (int idx = 0; (files != null) && (idx < files.length); idx++)
+ {
+ writeDataToDatabase(dataReader, files[idx]);
+ }
+ dataReader.getSink().end();
+ }
+
+ /**
+ * Reads the data from the given input streams and writes it to the database to which the given
+ * platform is connected. Only data that matches the given model will be written.
+ *
+ * @param platform The platform, must be connected to a live database
+ * @param model The model to which to constrain the written data
+ * @param input The input streams for the XML data
+ */
+ public void writeDataToDatabase(Platform platform, Database model, InputStream[] inputs) throws DdlUtilsException
+ {
+ DataReader dataReader = getConfiguredDataReader(platform, model);
+
+ dataReader.getSink().start();
+ for (int idx = 0; (inputs != null) && (idx < inputs.length); idx++)
+ {
+ writeDataToDatabase(dataReader, inputs[idx]);
+ }
+ dataReader.getSink().end();
+ }
+
+ /**
+ * Reads the data from the given input readers and writes it to the database to which the given
+ * platform is connected. Only data that matches the given model will be written.
+ *
+ * @param platform The platform, must be connected to a live database
+ * @param model The model to which to constrain the written data
+ * @param input The input readers for the XML data
+ */
+ public void writeDataToDatabase(Platform platform, Database model, Reader[] inputs) throws DdlUtilsException
+ {
+ DataReader dataReader = getConfiguredDataReader(platform, model);
+
+ dataReader.getSink().start();
+ for (int idx = 0; (inputs != null) && (idx < inputs.length); idx++)
+ {
+ writeDataToDatabase(dataReader, inputs[idx]);
+ }
+ dataReader.getSink().end();
+ }
+
+ /**
+ * Reads the data from the specified files and writes it to the database via the given data reader.
+ * Note that the sink that the data reader is configured with, won't be started or ended by
+ * this method. This has to be done by the code using this method.
+ *
+ * @param dataReader The data reader
+ * @param files The XML data files
+ */
+ public void writeDataToDatabase(DataReader dataReader, String[] files) throws DdlUtilsException
+ {
+ for (int idx = 0; (files != null) && (idx < files.length); idx++)
+ {
+ writeDataToDatabase(dataReader, files[idx]);
+ }
+ }
+
+ /**
+ * Reads the data from the given input stream and writes it to the database via the given data reader.
+ * Note that the input stream won't be closed by this method. Note also that the sink that the data
+ * reader is configured with, won't be started or ended by this method. This has to be done by the
+ * code using this method.
+ *
+ * @param dataReader The data reader
+ * @param input The input streams for the XML data
+ */
+ public void writeDataToDatabase(DataReader dataReader, InputStream[] inputs) throws DdlUtilsException
+ {
+ for (int idx = 0; (inputs != null) && (idx < inputs.length); idx++)
+ {
+ writeDataToDatabase(dataReader, inputs[idx]);
+ }
+ }
+
+ /**
+ * Reads the data from the given input stream and writes it to the database via the given data reader.
+ * Note that the input stream won't be closed by this method. Note also that the sink that the data
+ * reader is configured with, won't be started or ended by this method. This has to be done by the
+ * code using this method.
+ *
+ * @param dataReader The data reader
+ * @param input The input readers for the XML data
+ */
+ public void writeDataToDatabase(DataReader dataReader, Reader[] inputs) throws DdlUtilsException
+ {
+ for (int idx = 0; (inputs != null) && (idx < inputs.length); idx++)
+ {
+ writeDataToDatabase(dataReader, inputs[idx]);
+ }
+ }
+
+ /**
+ * Reads the data from the indicated XML file and writes it to the database via the given data reader.
+ * Note that the sink that the data reader is configured with, won't be started or ended by this method.
+ * This has to be done by the code using this method.
+ *
+ * @param dataReader The data reader
+ * @param path The path to the XML data file
+ */
+ public void writeDataToDatabase(DataReader dataReader, String path) throws DdlUtilsException
+ {
+ try
+ {
+ dataReader.parse(path);
+ }
+ catch (Exception ex)
+ {
+ throw new DdlUtilsException(ex);
+ }
+ }
+
+ /**
+ * Reads the data from the given input stream and writes it to the database via the given data reader.
+ * Note that the input stream won't be closed by this method. Note also that the sink that the data
+ * reader is configured with, won't be started or ended by this method. This has to be done by the
+ * code using this method.
+ *
+ * @param dataReader The data reader
+ * @param input The input stream for the XML data
+ */
+ public void writeDataToDatabase(DataReader dataReader, InputStream input) throws DdlUtilsException
+ {
+ try
+ {
+ dataReader.parse(input);
+ }
+ catch (Exception ex)
+ {
+ throw new DdlUtilsException(ex);
+ }
+ }
+
+ /**
+ * Reads the data from the given input stream and writes it to the database via the given data reader.
+ * Note that the input stream won't be closed by this method. Note also that the sink that the data
+ * reader is configured with, won't be started or ended by this method. This has to be done by the
+ * code using this method.
+ *
+ * @param dataReader The data reader
+ * @param input The input reader for the XML data
+ */
+ public void writeDataToDatabase(DataReader dataReader, Reader input) throws DdlUtilsException
+ {
+ try
+ {
+ dataReader.parse(input);
+ }
+ catch (Exception ex)
+ {
+ throw new DdlUtilsException(ex);
+ }
+ }
+}
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/io/Identity.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/io/Identity.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/io/Identity.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/io/Identity.java Thu Dec 14 23:30:52 2006
@@ -23,6 +23,8 @@
import java.util.Iterator;
import java.util.Map;
+import org.apache.ddlutils.model.Table;
+
/**
* Stores the identity of an database object as defined by its primary keys. Is used
* by {@link org.apache.ddlutils.io.DataToDatabaseSink} class for inserting objects
@@ -32,33 +34,43 @@
*/
public class Identity
{
- /** The name of the table. */
- private String _tableName;
+ /** The table. */
+ private Table _table;
/** The optional foreign key name whose referenced object this identity represents. */
private String _fkName;
/** The identity columns and their values. */
private HashMap _columnValues = new HashMap();
/**
- * Creates a new identity object for the indicated table.
+ * Creates a new identity object for the given table.
+ *
+ * @param table The name of the table
+ */
+ public Identity(Table table)
+ {
+ _table = table;
+ }
+
+ /**
+ * Creates a new identity object for the given table.
*
- * @param tableName The name of the table
+ * @param table The table
+ * @param fkName The name of the foreign key whose referenced object this identity represents
*/
- public Identity(String tableName)
+ public Identity(Table table, String fkName)
{
- _tableName = tableName;
+ _table = table;
+ _fkName = fkName;
}
/**
- * Creates a new identity object for the indicated table.
+ * Returns the table that this identity is for.
*
- * @param tableName The name of the table
- * @param fkName The name of the foreign key whose referenced object this identity represents
+ * @return The table
*/
- public Identity(String tableName, String fkName)
+ public Table getTable()
{
- _tableName = tableName;
- _fkName = fkName;
+ return _table;
}
/**
@@ -74,17 +86,28 @@
}
/**
- * Specifies the value for one of the identity columns.
+ * Specifies the value of the indicated identity columns.
*
* @param name The column name
* @param value The value for the column
*/
- public void setIdentityColumn(String name, Object value)
+ public void setColumnValue(String name, Object value)
{
_columnValues.put(name, value);
}
/**
+ * Returns the value of the indicated identity columns.
+ *
+ * @param name The column name
+ * @return The column's value
+ */
+ public Object getColumnValue(String name)
+ {
+ return _columnValues.get(name);
+ }
+
+ /**
* {@inheritDoc}
*/
public boolean equals(Object obj)
@@ -96,7 +119,7 @@
Identity otherIdentity = (Identity)obj;
- if (!_tableName.equals(otherIdentity._tableName))
+ if (!_table.equals(otherIdentity._table))
{
return false;
}
@@ -143,7 +166,7 @@
{
StringBuffer buffer = new StringBuffer();
- buffer.append(_tableName);
+ buffer.append(_table.getName());
buffer.append(":");
for (Iterator it = _columnValues.entrySet().iterator(); it.hasNext();)
{
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java Thu Dec 14 23:30:52 2006
@@ -481,6 +481,7 @@
{
_connection = null;
}
+ db.initialize();
return db;
}
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java Thu Dec 14 23:30:52 2006
@@ -85,6 +85,8 @@
private boolean _sqlCommentsOn = true;
/** Whether delimited identifiers are used or not. */
private boolean _delimitedIdentifierModeOn;
+ /** Whether identity override is enabled. */
+ private boolean _identityOverrideOn = true;
/** Whether read foreign keys shall be sorted alphabetically. */
private boolean _foreignKeysSorted;
@@ -195,6 +197,22 @@
/**
* {@inheritDoc}
*/
+ public boolean isIdentityOverrideOn()
+ {
+ return _identityOverrideOn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setIdentityOverrideOn(boolean identityOverrideOn)
+ {
+ _identityOverrideOn = identityOverrideOn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public boolean isForeignKeysSorted()
{
return _foreignKeysSorted;
@@ -1152,16 +1170,19 @@
if (bean.get(prop.getName()) != null)
{
// we ignore properties for which a value is present in the bean
- // only if they are auto-increment and the platform does not allow
- // the override of the auto-increment specification
- return getPlatformInfo().isIdentityOverrideAllowed() || !prop.getColumn().isAutoIncrement();
+ // only if they are identity and identity override is off or
+ // the platform does not allow the override of the auto-increment
+ // specification
+ return !prop.getColumn().isAutoIncrement() ||
+ (isIdentityOverrideOn() && getPlatformInfo().isIdentityOverrideAllowed());
}
else
{
// we also return properties without a value in the bean
// if they ain't auto-increment and don't have a default value
// in this case, a NULL is inserted
- return !prop.getColumn().isAutoIncrement() && (prop.getColumn().getDefaultValue() == null);
+ return !prop.getColumn().isAutoIncrement() &&
+ (prop.getColumn().getDefaultValue() == null);
}
}
});
@@ -1191,7 +1212,7 @@
// in INSERT/UPDATE statements, then we need to filter the corresponding
// columns out
return prop.getColumn().isAutoIncrement() &&
- (!getPlatformInfo().isIdentityOverrideAllowed() || (bean.get(prop.getName()) == null));
+ (!isIdentityOverrideOn() || !getPlatformInfo().isIdentityOverrideAllowed() || (bean.get(prop.getName()) == null));
}
});
@@ -1269,7 +1290,7 @@
}
catch (SQLException ex)
{
- throw new DatabaseOperationException("Error while inserting into the database", ex);
+ throw new DatabaseOperationException("Error while inserting into the database: " + ex.getMessage(), ex);
}
finally
{
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/task/ConvertingDatabaseCommand.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/task/ConvertingDatabaseCommand.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/task/ConvertingDatabaseCommand.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/task/ConvertingDatabaseCommand.java Thu Dec 14 23:30:52 2006
@@ -19,12 +19,8 @@
* under the License.
*/
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.apache.ddlutils.io.ConverterConfiguration;
import org.apache.ddlutils.io.DataConverterRegistration;
-import org.apache.tools.ant.BuildException;
+import org.apache.ddlutils.io.DatabaseDataIO;
/**
* Base type for database commands that use converters.
@@ -34,45 +30,26 @@
*/
public abstract class ConvertingDatabaseCommand extends DatabaseCommand
{
- /** The converters. */
- private ArrayList _converters = new ArrayList();
+ /** The database data io object. */
+ private DatabaseDataIO _dataIO = new DatabaseDataIO();
/**
- * Registers a converter.
+ * Returns the database data io object.
*
- * @param converterRegistration The registration info
+ * @return The data io object
*/
- public void addConfiguredConverter(DataConverterRegistration converterRegistration)
+ protected DatabaseDataIO getDataIO()
{
- _converters.add(converterRegistration);
+ return _dataIO;
}
/**
- * Registers the converters at the given configuration.
+ * Registers a converter.
*
- * @param converterConf The converter configuration
+ * @param converterRegistration The registration info
*/
- protected void registerConverters(ConverterConfiguration converterConf) throws BuildException
+ public void addConfiguredConverter(DataConverterRegistration converterRegistration)
{
- for (Iterator it = _converters.iterator(); it.hasNext();)
- {
- DataConverterRegistration registrationInfo = (DataConverterRegistration)it.next();
-
- if (registrationInfo.getTypeCode() != Integer.MIN_VALUE)
- {
- converterConf.registerConverter(registrationInfo.getTypeCode(),
- registrationInfo.getConverter());
- }
- else
- {
- if ((registrationInfo.getTable() == null) || (registrationInfo.getColumn() == null))
- {
- throw new BuildException("Please specify either the jdbc type or a table/column pair for which the converter shall be defined");
- }
- converterConf.registerConverter(registrationInfo.getTable(),
- registrationInfo.getColumn(),
- registrationInfo.getConverter());
- }
- }
+ _dataIO.registerConverter(converterRegistration);
}
}
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToDatabaseCommand.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToDatabaseCommand.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToDatabaseCommand.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToDatabaseCommand.java Thu Dec 14 23:30:52 2006
@@ -24,9 +24,7 @@
import java.util.Iterator;
import org.apache.commons.lang.exception.ExceptionUtils;
-import org.apache.ddlutils.Platform;
import org.apache.ddlutils.io.DataReader;
-import org.apache.ddlutils.io.DataToDatabaseSink;
import org.apache.ddlutils.model.Database;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
@@ -56,12 +54,6 @@
private File _singleDataFile = null;
/** The input files. */
private ArrayList _fileSets = new ArrayList();
- /** Whether foreign key order shall be followed when inserting data into the database. */
- private boolean _ensureFKOrder = true;
- /** Whether we should use batch mode. */
- private Boolean _useBatchMode;
- /** The maximum number of objects to insert in one batch. */
- private Integer _batchSize;
/**
* Adds a fileset.
@@ -94,7 +86,7 @@
*/
public void setBatchSize(int batchSize)
{
- _batchSize = new Integer(batchSize);
+ getDataIO().setBatchSize(new Integer(batchSize));
}
/**
@@ -110,7 +102,7 @@
*/
public void setUseBatchMode(boolean useBatchMode)
{
- _useBatchMode = Boolean.valueOf(useBatchMode);
+ getDataIO().setUseBatchMode(useBatchMode);
}
/**
@@ -125,7 +117,7 @@
*/
public void setEnsureForeignKeyOrder(boolean ensureFKOrder)
{
- _ensureFKOrder = ensureFKOrder;
+ getDataIO().setEnsureFKOrder(ensureFKOrder);
}
/**
@@ -133,32 +125,20 @@
*/
public void execute(Task task, Database model) throws BuildException
{
- try
+ if ((_singleDataFile != null) && !_fileSets.isEmpty())
{
- Platform platform = getPlatform();
- DataToDatabaseSink sink = new DataToDatabaseSink(platform, model);
- DataReader reader = new DataReader();
+ throw new BuildException("Please use either the datafile attribute or the sub fileset element, but not both");
+ }
- sink.setEnsureForeignKeyOrder(_ensureFKOrder);
- if (_useBatchMode != null)
- {
- sink.setUseBatchMode(_useBatchMode.booleanValue());
- if (_batchSize != null)
- {
- sink.setBatchSize(_batchSize.intValue());
- }
- }
-
- reader.setModel(model);
- reader.setSink(sink);
- registerConverters(reader.getConverterConfiguration());
- if ((_singleDataFile != null) && !_fileSets.isEmpty())
- {
- throw new BuildException("Please use either the datafile attribute or the sub fileset element, but not both");
- }
+ DataReader dataReader = null;
+
+ try
+ {
+ dataReader = getDataIO().getConfiguredDataReader(getPlatform(), model);
+ dataReader.getSink().start();
if (_singleDataFile != null)
{
- readSingleDataFile(task, reader, _singleDataFile);
+ readSingleDataFile(task, dataReader, _singleDataFile);
}
else
{
@@ -171,7 +151,7 @@
for (int idx = 0; (files != null) && (idx < files.length); idx++)
{
- readSingleDataFile(task, reader, new File(fileSetDir, files[idx]));
+ readSingleDataFile(task, dataReader, new File(fileSetDir, files[idx]));
}
}
}
@@ -187,6 +167,13 @@
throw new BuildException(ex);
}
}
+ finally
+ {
+ if (dataReader != null)
+ {
+ dataReader.getSink().end();
+ }
+ }
}
/**
@@ -214,7 +201,7 @@
{
try
{
- reader.parse(dataFile);
+ getDataIO().writeDataToDatabase(reader, dataFile.getAbsolutePath());
task.log("Written data file "+dataFile.getAbsolutePath() + " to database", Project.MSG_INFO);
}
catch (Exception ex)
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToFileCommand.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToFileCommand.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToFileCommand.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteDataToFileCommand.java Thu Dec 14 23:30:52 2006
@@ -22,10 +22,7 @@
import java.io.File;
import java.io.FileOutputStream;
-import org.apache.ddlutils.Platform;
-import org.apache.ddlutils.io.DataWriter;
import org.apache.ddlutils.model.Database;
-import org.apache.ddlutils.model.Table;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
@@ -72,22 +69,8 @@
{
try
{
- Platform platform = getPlatform();
- DataWriter writer = new DataWriter(new FileOutputStream(_outputFile), _encoding);
- Table[] tables = new Table[1];
-
- registerConverters(writer.getConverterConfiguration());
-
- // TODO: An advanced algorithm could be employed here that writes objects
- // related by foreign keys, in the correct order
- writer.writeDocumentStart();
- for (int idx = 0; idx < model.getTableCount(); idx++)
- {
- tables[0] = (Table)model.getTable(idx);
-
- writer.write(platform.query(model, "select * from "+tables[0].getName(), tables));
- }
- writer.writeDocumentEnd();
+ getDataIO().writeDataToXML(getPlatform(),
+ new FileOutputStream(_outputFile), _encoding);
}
catch (Exception ex)
{
Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/RunAllTests.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/RunAllTests.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/test/org/apache/ddlutils/RunAllTests.java (original)
+++ db/ddlutils/trunk/src/test/org/apache/ddlutils/RunAllTests.java Thu Dec 14 23:30:52 2006
@@ -27,6 +27,7 @@
import org.apache.ddlutils.io.TestDataReaderAndWriter;
import org.apache.ddlutils.io.TestDatabaseIO;
import org.apache.ddlutils.io.TestDatatypes;
+import org.apache.ddlutils.io.TestMisc;
import org.apache.ddlutils.io.converters.TestDateConverter;
import org.apache.ddlutils.io.converters.TestTimeConverter;
import org.apache.ddlutils.model.TestArrayAccessAtTable;
@@ -125,6 +126,7 @@
suite.addTestSuite(TestDatatypes.class);
suite.addTestSuite(TestConstraints.class);
suite.addTestSuite(TestAlteration.class);
+ suite.addTestSuite(TestMisc.class);
}
return suite;
Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/TestDatabaseWriterBase.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/TestDatabaseWriterBase.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/test/org/apache/ddlutils/TestDatabaseWriterBase.java (original)
+++ db/ddlutils/trunk/src/test/org/apache/ddlutils/TestDatabaseWriterBase.java Thu Dec 14 23:30:52 2006
@@ -293,7 +293,9 @@
dataReader.setModel(_model);
dataReader.setSink(new DataToDatabaseSink(getPlatform(), _model));
+ dataReader.getSink().start();
dataReader.parse(new StringReader(dataXml));
+ dataReader.getSink().end();
return _model;
}
catch (Exception ex)
Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDataReaderAndWriter.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDataReaderAndWriter.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDataReaderAndWriter.java (original)
+++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDataReaderAndWriter.java Thu Dec 14 23:30:52 2006
@@ -106,6 +106,7 @@
public void end() throws DataSinkException
{}
});
+ // no need to call start/end as the don't do anything anyways
dataReader.parse(new StringReader(testDataXml));
assertEquals(5, readObjects.size());
@@ -215,6 +216,7 @@
public void end() throws DataSinkException
{}
});
+ // no need to call start/end as the don't do anything anyways
dataReader.parse(new StringReader(dataXml));
assertEquals(1, readObjects.size());
Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatatypes.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatatypes.java?view=diff&rev=487473&r1=487472&r2=487473
==============================================================================
--- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatatypes.java (original)
+++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatatypes.java Thu Dec 14 23:30:52 2006
@@ -145,6 +145,7 @@
sink.setUseBatchMode(false);
reader.setModel(getModel());
reader.setSink(sink);
+ sink.start();
try
{
reader.parse(new StringReader(dataSql));
@@ -152,6 +153,10 @@
catch (Exception ex)
{
throw new RuntimeException(ex);
+ }
+ finally
+ {
+ sink.end();
}
beans = getRows("roundtrip");
Added: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestMisc.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestMisc.java?view=auto&rev=487473
==============================================================================
--- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestMisc.java (added)
+++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestMisc.java Thu Dec 14 23:30:52 2006
@@ -0,0 +1,257 @@
+package org.apache.ddlutils.io;
+
+/*
+ * 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.
+ */
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.List;
+
+import junit.framework.Test;
+
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.xml.sax.InputSource;
+
+/**
+ * Contains misc tests.
+ *
+ * @version $Revision: $
+ */
+public class TestMisc extends RoundtripTestBase
+{
+ /**
+ * Parameterized test case pattern.
+ *
+ * @return The tests
+ */
+ public static Test suite() throws Exception
+ {
+ return getTests(TestMisc.class);
+ }
+
+ /**
+ * Tests the backup of restore of a table with an identity column and a foreign key to
+ * it when identity override is turned on.
+ */
+ public void testIdentityOverrideOn() throws Exception
+ {
+ if (!getPlatformInfo().isIdentityOverrideAllowed())
+ {
+ // TODO: for testing these platforms, we need deleteRows
+ return;
+ }
+ final String modelXml =
+ "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
+ "<database name='roundtriptest'>\n"+
+ " <table name='misc1'>\n"+
+ " <column name='pk' type='INTEGER' primaryKey='true' required='true' autoIncrement='true'/>\n"+
+ " <column name='avalue' type='INTEGER' required='false'/>\n"+
+ " </table>\n"+
+ " <table name='misc2'>\n"+
+ " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
+ " <column name='fk' type='INTEGER' required='false'/>\n"+
+ " <foreign-key name='test' foreignTable='misc1'>\n"+
+ " <reference local='fk' foreign='pk'/>\n"+
+ " </foreign-key>\n"+
+ " </table>\n"+
+ "</database>";
+
+ createDatabase(modelXml);
+
+ insertRow("misc1", new Object[] { new Integer(10), new Integer(1) });
+ insertRow("misc1", new Object[] { new Integer(12), new Integer(2) });
+ insertRow("misc1", new Object[] { new Integer(13), new Integer(3) });
+ insertRow("misc2", new Object[] { new Integer(1), new Integer(10) });
+ insertRow("misc2", new Object[] { new Integer(2), new Integer(13) });
+
+ StringWriter stringWriter = new StringWriter();
+ DatabaseDataIO dataIO = new DatabaseDataIO();
+
+ dataIO.writeDataToXML(getPlatform(), stringWriter, "UTF-8");
+
+ String dataAsXml = stringWriter.toString();
+ SAXReader reader = new SAXReader();
+ Document testDoc = reader.read(new InputSource(new StringReader(dataAsXml)));
+
+ if (getPlatform().isDelimitedIdentifierModeOn())
+ {
+ List misc1Rows = testDoc.selectNodes("//misc1");
+ List misc2Rows = testDoc.selectNodes("//misc2");
+
+ assertEquals(3, misc1Rows.size());
+ assertEquals("10", ((Element)misc1Rows.get(0)).attributeValue("pk"));
+ assertEquals("1", ((Element)misc1Rows.get(0)).attributeValue("avalue"));
+ assertEquals("12", ((Element)misc1Rows.get(1)).attributeValue("pk"));
+ assertEquals("2", ((Element)misc1Rows.get(1)).attributeValue("avalue"));
+ assertEquals("13", ((Element)misc1Rows.get(2)).attributeValue("pk"));
+ assertEquals("3", ((Element)misc1Rows.get(2)).attributeValue("avalue"));
+ assertEquals(2, misc2Rows.size());
+ assertEquals("1", ((Element)misc2Rows.get(0)).attributeValue("pk"));
+ assertEquals("10", ((Element)misc2Rows.get(0)).attributeValue("fk"));
+ assertEquals("2", ((Element)misc2Rows.get(1)).attributeValue("pk"));
+ assertEquals("13", ((Element)misc2Rows.get(1)).attributeValue("fk"));
+ }
+ else
+ {
+ List misc1Rows = testDoc.selectNodes("//MISC1");
+ List misc2Rows = testDoc.selectNodes("//MISC2");
+
+ assertEquals(3, misc1Rows.size());
+ assertEquals("10", ((Element)misc1Rows.get(0)).attributeValue("PK"));
+ assertEquals("1", ((Element)misc1Rows.get(0)).attributeValue("AVALUE"));
+ assertEquals("12", ((Element)misc1Rows.get(1)).attributeValue("PK"));
+ assertEquals("2", ((Element)misc1Rows.get(1)).attributeValue("AVALUE"));
+ assertEquals("13", ((Element)misc1Rows.get(2)).attributeValue("PK"));
+ assertEquals("3", ((Element)misc1Rows.get(2)).attributeValue("AVALUE"));
+ assertEquals(2, misc2Rows.size());
+ assertEquals("1", ((Element)misc2Rows.get(0)).attributeValue("PK"));
+ assertEquals("10", ((Element)misc2Rows.get(0)).attributeValue("FK"));
+ assertEquals("2", ((Element)misc2Rows.get(1)).attributeValue("PK"));
+ assertEquals("13", ((Element)misc2Rows.get(1)).attributeValue("FK"));
+ }
+
+ dropDatabase();
+ createDatabase(modelXml);
+
+ StringReader stringReader = new StringReader(dataAsXml);
+
+ dataIO.writeDataToDatabase(getPlatform(), new Reader[] { stringReader });
+
+ List beans = getRows("misc1");
+
+ assertEquals(new Integer(10), beans.get(0), "pk");
+ assertEquals(new Integer(1), beans.get(0), "avalue");
+ assertEquals(new Integer(12), beans.get(1), "pk");
+ assertEquals(new Integer(2), beans.get(1), "avalue");
+ assertEquals(new Integer(13), beans.get(2), "pk");
+ assertEquals(new Integer(3), beans.get(2), "avalue");
+
+ beans = getRows("misc2");
+
+ assertEquals(new Integer(1), beans.get(0), "pk");
+ assertEquals(new Integer(10), beans.get(0), "fk");
+ assertEquals(new Integer(2), beans.get(1), "pk");
+ assertEquals(new Integer(13), beans.get(1), "fk");
+ }
+
+ /**
+ * Tests the backup of restore of a table with an identity column and a foreign key to
+ * it when identity override is turned off.
+ */
+ public void testIdentityOverrideOff() throws Exception
+ {
+ final String modelXml =
+ "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
+ "<database name='roundtriptest'>\n"+
+ " <table name='misc1'>\n"+
+ " <column name='pk' type='INTEGER' primaryKey='true' required='true' autoIncrement='true'/>\n"+
+ " <column name='avalue' type='INTEGER' required='false'/>\n"+
+ " </table>\n"+
+ " <table name='misc2'>\n"+
+ " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
+ " <column name='fk' type='INTEGER' required='false'/>\n"+
+ " <foreign-key name='test' foreignTable='misc1'>\n"+
+ " <reference local='fk' foreign='pk'/>\n"+
+ " </foreign-key>\n"+
+ " </table>\n"+
+ "</database>";
+
+ createDatabase(modelXml);
+
+ insertRow("misc1", new Object[] { new Integer(10), new Integer(1) });
+ insertRow("misc1", new Object[] { new Integer(12), new Integer(2) });
+ insertRow("misc1", new Object[] { new Integer(13), new Integer(3) });
+ insertRow("misc2", new Object[] { new Integer(1), new Integer(10) });
+ insertRow("misc2", new Object[] { new Integer(2), new Integer(13) });
+
+ StringWriter stringWriter = new StringWriter();
+ DatabaseDataIO dataIO = new DatabaseDataIO();
+
+ dataIO.writeDataToXML(getPlatform(), stringWriter, "UTF-8");
+
+ String dataAsXml = stringWriter.toString();
+ SAXReader reader = new SAXReader();
+ Document testDoc = reader.read(new InputSource(new StringReader(dataAsXml)));
+
+ if (getPlatform().isDelimitedIdentifierModeOn())
+ {
+ List misc1Rows = testDoc.selectNodes("//misc1");
+ List misc2Rows = testDoc.selectNodes("//misc2");
+
+ assertEquals(3, misc1Rows.size());
+ assertEquals("10", ((Element)misc1Rows.get(0)).attributeValue("pk"));
+ assertEquals("1", ((Element)misc1Rows.get(0)).attributeValue("avalue"));
+ assertEquals("12", ((Element)misc1Rows.get(1)).attributeValue("pk"));
+ assertEquals("2", ((Element)misc1Rows.get(1)).attributeValue("avalue"));
+ assertEquals("13", ((Element)misc1Rows.get(2)).attributeValue("pk"));
+ assertEquals("3", ((Element)misc1Rows.get(2)).attributeValue("avalue"));
+ assertEquals(2, misc2Rows.size());
+ assertEquals("1", ((Element)misc2Rows.get(0)).attributeValue("pk"));
+ assertEquals("10", ((Element)misc2Rows.get(0)).attributeValue("fk"));
+ assertEquals("2", ((Element)misc2Rows.get(1)).attributeValue("pk"));
+ assertEquals("13", ((Element)misc2Rows.get(1)).attributeValue("fk"));
+ }
+ else
+ {
+ List misc1Rows = testDoc.selectNodes("//MISC1");
+ List misc2Rows = testDoc.selectNodes("//MISC2");
+
+ assertEquals(3, misc1Rows.size());
+ assertEquals("10", ((Element)misc1Rows.get(0)).attributeValue("PK"));
+ assertEquals("1", ((Element)misc1Rows.get(0)).attributeValue("AVALUE"));
+ assertEquals("12", ((Element)misc1Rows.get(1)).attributeValue("PK"));
+ assertEquals("2", ((Element)misc1Rows.get(1)).attributeValue("AVALUE"));
+ assertEquals("13", ((Element)misc1Rows.get(2)).attributeValue("PK"));
+ assertEquals("3", ((Element)misc1Rows.get(2)).attributeValue("AVALUE"));
+ assertEquals(2, misc2Rows.size());
+ assertEquals("1", ((Element)misc2Rows.get(0)).attributeValue("PK"));
+ assertEquals("10", ((Element)misc2Rows.get(0)).attributeValue("FK"));
+ assertEquals("2", ((Element)misc2Rows.get(1)).attributeValue("PK"));
+ assertEquals("13", ((Element)misc2Rows.get(1)).attributeValue("FK"));
+ }
+
+ dropDatabase();
+ createDatabase(modelXml);
+
+ getPlatform().setIdentityOverrideOn(false);
+
+ StringReader stringReader = new StringReader(dataAsXml);
+
+ dataIO.writeDataToDatabase(getPlatform(), new Reader[] { stringReader });
+
+ List beans = getRows("misc1");
+
+ assertEquals(new Integer(1), beans.get(0), "pk");
+ assertEquals(new Integer(1), beans.get(0), "avalue");
+ assertEquals(new Integer(2), beans.get(1), "pk");
+ assertEquals(new Integer(2), beans.get(1), "avalue");
+ assertEquals(new Integer(3), beans.get(2), "pk");
+ assertEquals(new Integer(3), beans.get(2), "avalue");
+
+ beans = getRows("misc2");
+
+ assertEquals(new Integer(1), beans.get(0), "pk");
+ assertEquals(new Integer(1), beans.get(0), "fk");
+ assertEquals(new Integer(2), beans.get(1), "pk");
+ assertEquals(new Integer(3), beans.get(1), "fk");
+ }
+}