/* * Copyright (C) 2004 Anthony Smith * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * ---------------------------------------------------------------------------- * TITLE $Id$ * --------------------------------------------------------------------------- * * --------------------------------------------------------------------------*/ package opendbcopy.plugin.script; import opendbcopy.config.APM; import opendbcopy.config.XMLTags; import opendbcopy.connection.DBConnection; import opendbcopy.connection.exception.DriverNotFoundException; import opendbcopy.connection.exception.OpenConnectionException; import opendbcopy.controller.MainController; import opendbcopy.io.Writer; import opendbcopy.plugin.model.DynamicPluginThread; import opendbcopy.plugin.model.Model; import opendbcopy.plugin.model.database.DatabaseModel; import opendbcopy.plugin.model.database.exception.DependencyNotSolvableException; import opendbcopy.plugin.model.database.typeinfo.TypeInfo; import opendbcopy.plugin.model.database.typeinfo.TypeInfoHelper; import opendbcopy.plugin.model.exception.MissingAttributeException; import opendbcopy.plugin.model.exception.MissingElementException; import opendbcopy.plugin.model.exception.PluginException; import opendbcopy.plugin.model.exception.UnsupportedAttributeValueException; import opendbcopy.sql.Helper; import opendbcopy.util.InputOutputHelper; import opendbcopy.util.IntHashMap; import org.jdom.Element; import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; /** * class description * * @author Anthony Smith * @version $Revision$ */ public class InsertScriptPlugin extends DynamicPluginThread { private DatabaseModel model; private Connection connSource; private Statement stmSource; private ResultSet rs; private StringBuffer sbScript; private File outputPath; private String database = ""; private String identifierQuoteStringOut = ""; private List processTables = null; private boolean show_qualified_table_name = false; private int counterRecords = 0; private int counterTables = 0; /** * Creates a new InsertScriptPlugin object. * * @param controller DOCUMENT ME! * @param baseModel DOCUMENT ME! * * @throws PluginException DOCUMENT ME! */ public InsertScriptPlugin(MainController controller, Model baseModel) throws PluginException { super(controller, baseModel); this.model = (DatabaseModel) baseModel; } /** * DOCUMENT ME! * * @throws PluginException DOCUMENT ME! */ protected void setUp() throws PluginException { try { // read the plugin configuration Element conf = model.getConf(); outputPath = new File(conf.getChild(XMLTags.DIR).getAttributeValue(XMLTags.VALUE)); if (!outputPath.exists()) { boolean mkDirOk = outputPath.mkdir(); if (!mkDirOk) { throw new PluginException("Could not create " + outputPath.getAbsolutePath()); } } show_qualified_table_name = Boolean.valueOf(conf.getChild(XMLTags.SHOW_QUALIFIED_TABLE_NAME).getAttributeValue(XMLTags.VALUE)).booleanValue(); if (model.getDbMode() == model.DUAL_MODE) { identifierQuoteStringOut = model.getDestinationMetadata().getChild(XMLTags.IDENTIFIER_QUOTE_STRING).getAttributeValue(XMLTags.VALUE); database = model.getDestinationDb().getName(); } else { identifierQuoteStringOut = model.getSourceMetadata().getChild(XMLTags.IDENTIFIER_QUOTE_STRING).getAttributeValue(XMLTags.VALUE); database = model.getSourceDb().getName(); } // get connection connSource = DBConnection.getConnection(model.getSourceConnection()); // extract the tables to dump if (model.getDbMode() == model.DUAL_MODE) { processTables = model.getDestinationTablesToProcessOrdered(); } else { processTables = model.getSourceTablesToProcessOrdered(); } // now set the number of tables that need to be copied model.setLengthProgressTable(processTables.size()); } catch (UnsupportedAttributeValueException e) { throw new PluginException(e); } catch (MissingAttributeException e) { throw new PluginException(e); } catch (MissingElementException e) { throw new PluginException(e); } catch (DependencyNotSolvableException e) { throw new PluginException(e); } catch (OpenConnectionException e) { throw new PluginException(e); } catch (DriverNotFoundException e) { throw new PluginException(e); } } /** * DOCUMENT ME! * * @throws PluginException DOCUMENT ME! */ public void execute() throws PluginException { try { stmSource = connSource.createStatement(); ArrayList generatedFiles = new ArrayList(); String sourceTableName = ""; String destinationTableName = ""; String qualifiedTableName = ""; String tableName = ""; String fileName = ""; String selectStm = ""; Iterator itProcessTables = processTables.iterator(); while (itProcessTables.hasNext() && !isInterrupted()) { Element tableProcess = (Element) itProcessTables.next(); List processColumns = null; counterRecords = 0; if (model.getDbMode() == model.DUAL_MODE) { sourceTableName = tableProcess.getAttributeValue(XMLTags.SOURCE_DB); destinationTableName = tableProcess.getAttributeValue(XMLTags.DESTINATION_DB); processColumns = model.getMappingColumnsToProcessByDestinationTable(destinationTableName); fileName = counterTables + "_" + destinationTableName + ".sql"; selectStm = Helper.getSelectStatement(model, sourceTableName, XMLTags.SOURCE_DB, processColumns); if (show_qualified_table_name) { qualifiedTableName = model.getQualifiedDestinationTableName(destinationTableName); } else { qualifiedTableName = destinationTableName; } tableName = destinationTableName; } else { sourceTableName = tableProcess.getAttributeValue(XMLTags.NAME); processColumns = model.getSourceColumnsToProcess(sourceTableName); fileName = counterTables + "_" + sourceTableName + ".sql"; selectStm = Helper.getSelectStatement(model, sourceTableName, XMLTags.NAME, processColumns); if (show_qualified_table_name) { qualifiedTableName = model.getQualifiedSourceTableName(sourceTableName); } else { qualifiedTableName = sourceTableName; } tableName = sourceTableName; } // Reading number of records for progress bar model.setLengthProgressRecord(Helper.getNumberOfRecordsFiltered(stmSource, model, XMLTags.SOURCE_DB, sourceTableName)); model.setCurrentProgressRecord(counterRecords); model.setProgressMessage("Reading " + qualifiedTableName + " ..."); logger.info("Reading " + qualifiedTableName + " ..."); // initalise stringBuffer sbScript and script header initScriptHeader(qualifiedTableName, counterTables); ResultSet srcResult = stmSource.executeQuery(selectStm); genInserts(srcResult, tableName, qualifiedTableName, processColumns, sbScript); srcResult.close(); File file = new File(outputPath.getAbsolutePath() + APM.FILE_SEP + fileName); Writer.write(sbScript, file); generatedFiles.add(file); model.setCurrentProgressTable(++counterTables); logger.info(counterRecords + " records written to file " + fileName); } if (!isInterrupted()) { logger.info(counterTables + " table(s) processed"); File[] outputFiles = new File[generatedFiles.size()]; outputFiles = (File[]) generatedFiles.toArray(outputFiles); Element outputConf = model.getConf().getChild(XMLTags.OUTPUT); model.appendToOutput(InputOutputHelper.createFileListElement(outputFiles, outputConf.getChild(XMLTags.FILELIST).getAttributeValue(XMLTags.VALUE))); } } catch (UnsupportedAttributeValueException e) { throw new PluginException(e); } catch (MissingAttributeException e) { throw new PluginException(e); } catch (MissingElementException e) { throw new PluginException(e); } catch (SQLException e) { throw new PluginException(e); } catch (IOException e) { throw new PluginException(e); } catch (Exception e) { throw new PluginException(e); } } /** * DOCUMENT ME! * * @param srcResult DOCUMENT ME! * @param tableName DOCUMENT ME! * @param qualifiedTableName DOCUMENT ME! * @param processColumns DOCUMENT ME! * @param sbScript DOCUMENT ME! * * @throws IllegalArgumentException DOCUMENT ME! * @throws UnsupportedAttributeValueException DOCUMENT ME! * @throws MissingAttributeException DOCUMENT ME! * @throws MissingElementException DOCUMENT ME! * @throws SQLException DOCUMENT ME! */ private void genInserts(ResultSet srcResult, String tableName, String qualifiedTableName, List processColumns, StringBuffer sbScript) throws IllegalArgumentException, UnsupportedAttributeValueException, MissingAttributeException, MissingElementException, SQLException { Iterator itProcessColumns = processColumns.iterator(); StringBuffer sbColumnNames = new StringBuffer(); int nbrCols = 1; IntHashMap colTypeInfo = new IntHashMap(); while (itProcessColumns.hasNext()) { Element column = (Element) itProcessColumns.next(); if (model.getDbMode() == model.DUAL_MODE) { column = model.getDestinationColumn(tableName, column.getAttributeValue(XMLTags.DESTINATION_DB)); } sbColumnNames.append(column.getAttributeValue(XMLTags.NAME)); colTypeInfo.put(nbrCols, new TypeInfo(model.getTypeInfoByTypeName(column.getAttributeValue(XMLTags.TYPE_NAME), database))); if (nbrCols < processColumns.size()) { sbColumnNames.append(", "); nbrCols++; } } String in = null; while (srcResult.next() && !isInterrupted()) { sbScript.append("insert into "); sbScript.append(qualifiedTableName); sbScript.append(" (" + sbColumnNames.toString() + ")"); sbScript.append(" values ("); // read columns and append them for (int i = 1; i < (nbrCols + 1); i++) { in = srcResult.getString(i); if (srcResult.wasNull()) { sbScript.append("null"); } else { sbScript.append(TypeInfoHelper.getFormattedString(in, (TypeInfo) colTypeInfo.get(i), identifierQuoteStringOut)); } if (i < (nbrCols)) { sbScript.append(", "); } } sbScript.append(");"); sbScript.append(APM.LINE_SEP); model.setCurrentProgressRecord(++counterRecords); } } /** * DOCUMENT ME! * * @param tableName DOCUMENT ME! * @param processOrder DOCUMENT ME! */ private void initScriptHeader(String tableName, int processOrder) { sbScript = new StringBuffer(); sbScript.append("#############################################################################" + APM.LINE_SEP); sbScript.append("#" + APM.LINE_SEP); sbScript.append("# Script for table " + tableName + APM.LINE_SEP); sbScript.append("#" + APM.LINE_SEP); sbScript.append("# Load this script as #" + processOrder + " if there are referential integrity constraints set" + APM.LINE_SEP); sbScript.append("#" + APM.LINE_SEP); sbScript.append("# generated on " + new Date().toString() + APM.LINE_SEP); sbScript.append("#" + APM.LINE_SEP); sbScript.append("#############################################################################" + APM.LINE_SEP); } }