/** * Licensed to JumpMind Inc under one or more contributor * license agreements. See the NOTICE file distributed * with this work for additional information regarding * copyright ownership. JumpMind Inc licenses this file * to you under the GNU General Public License, version 3.0 (GPLv3) * (the "License"); you may not use this file except in compliance * with the License. * * You should have received a copy of the GNU General Public License, * version 3.0 (GPLv3) along with this library; if not, see * <http://www.gnu.org/licenses/>. * * 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. */ /* O * Licensed to JumpMind Inc under one or more contributor * license agreements. See the NOTICE file distributed * with this work for additional information regarding * copyright ownership. JumpMind Inc licenses this file * to you under the GNU Lesser General Public License (the * "License"); you may not use this file except in compliance * with the License. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * <http://www.gnu.org/licenses/>. * * 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. */ package org.jumpmind.symmetric.io.data; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.jumpmind.db.model.Table; import org.jumpmind.db.platform.IDatabasePlatform; import org.jumpmind.db.util.BinaryEncoding; import org.jumpmind.exception.IoException; import org.jumpmind.symmetric.io.data.reader.CsvTableDataReader; import org.jumpmind.symmetric.io.data.reader.SqlDataReader; import org.jumpmind.symmetric.io.data.reader.SymXmlDataReader; import org.jumpmind.symmetric.io.data.reader.XmlDataReader; import org.jumpmind.symmetric.io.data.writer.Conflict; import org.jumpmind.symmetric.io.data.writer.Conflict.DetectConflict; import org.jumpmind.symmetric.io.data.writer.Conflict.ResolveConflict; import org.jumpmind.symmetric.io.data.writer.DefaultDatabaseWriter; import org.jumpmind.symmetric.io.data.writer.DatabaseWriterErrorIgnorer; import org.jumpmind.symmetric.io.data.writer.DatabaseWriterSettings; import org.jumpmind.symmetric.io.data.writer.IDatabaseWriterFilter; /** * Import data from file to database tables. */ public class DbImport { public enum Format { SQL, CSV, XML, SYM_XML }; private Format format = Format.SQL; private String catalog; private String schema; private long commitRate = 10000; private int interval = 5; private boolean useVariableDates = false; /** * Force the import to continue, regardless of errors that might occur. */ private boolean forceImport = false; /** * If a row already exists, then replace it using an update statement. */ private boolean replaceRows = false; /** * Ignore rows that already exist. */ private boolean ignoreCollisions = false; private boolean alterCaseToMatchDatabaseDefaultCase = false; private boolean alterTables = false; private boolean dropIfExists = false; private boolean ignoreMissingTables = true; protected IDatabasePlatform platform; protected List<IDatabaseWriterFilter> databaseWriterFilters; public DbImport() { this.databaseWriterFilters = new ArrayList<IDatabaseWriterFilter>(); } public DbImport(IDatabasePlatform platform) { this(); this.platform = platform; } public void importTables(String importData, String tableName) { try { ByteArrayInputStream in = new ByteArrayInputStream(importData.getBytes()); importTables(in, tableName); in.close(); } catch (IOException e) { throw new IoException(e); } } public void importTables(String importData) { try { ByteArrayInputStream in = new ByteArrayInputStream(importData.getBytes()); importTables(in); in.close(); } catch (IOException e) { throw new IoException(e); } } public void importTables(InputStream in) { importTables(in, null); } public void importTables(InputStream in, String tableName) { if (format == Format.SQL) { importTablesFromSql(in); } else if (format == Format.CSV) { importTablesFromCsv(in, tableName); } else if (format == Format.XML) { importTablesFromXml(in); } else if (format == Format.SYM_XML) { importTablesFromSymXml(in); } } protected Conflict buildConflictSettings() { Conflict conflict = new Conflict(); conflict.setDetectType(DetectConflict.USE_PK_DATA); if (replaceRows) { conflict.setResolveType(ResolveConflict.FALLBACK); } else if (forceImport || ignoreCollisions) { conflict.setResolveType(ResolveConflict.IGNORE); } else { conflict.setResolveType(ResolveConflict.MANUAL); } return conflict; } protected DatabaseWriterSettings buildDatabaseWriterSettings() { DatabaseWriterSettings settings = new DatabaseWriterSettings(); settings.setMaxRowsBeforeCommit(commitRate); settings.setCommitSleepInterval(interval); settings.setDefaultConflictSetting(buildConflictSettings()); settings.setUsePrimaryKeysFromSource(false); settings.setAlterTable(alterTables); settings.setCreateTableDropFirst(dropIfExists); settings.setCreateTableFailOnError(!forceImport); settings.setDatabaseWriterFilters(databaseWriterFilters); settings.setIgnoreMissingTables(ignoreMissingTables); settings.setCreateTableAlterCaseToMatchDatabaseDefault(alterCaseToMatchDatabaseDefaultCase); if (forceImport) { settings.addErrorHandler(new DatabaseWriterErrorIgnorer()); } return settings; } protected void importTablesFromCsv(InputStream in, String tableName) { Table table = platform.readTableFromDatabase(catalog, schema, tableName); if (table == null) { throw new RuntimeException("Unable to find table"); } CsvTableDataReader reader = new CsvTableDataReader(BinaryEncoding.HEX, table.getCatalog(), table.getSchema(), table.getName(), in); DefaultDatabaseWriter writer = new DefaultDatabaseWriter(platform, buildDatabaseWriterSettings()); DataProcessor dataProcessor = new DataProcessor(reader, writer, "import"); dataProcessor.process(); } protected void importTablesFromXml(InputStream in) { XmlDataReader reader = new XmlDataReader(in); DefaultDatabaseWriter writer = new DefaultDatabaseWriter(platform, buildDatabaseWriterSettings()); DataProcessor dataProcessor = new DataProcessor(reader, writer, "import"); dataProcessor.process(); } protected void importTablesFromSymXml(InputStream in) { SymXmlDataReader reader = new SymXmlDataReader(in); DefaultDatabaseWriter writer = new DefaultDatabaseWriter(platform, buildDatabaseWriterSettings()); DataProcessor dataProcessor = new DataProcessor(reader, writer, "import"); dataProcessor.process(); } protected void importTablesFromSql(InputStream in) { SqlDataReader reader = new SqlDataReader(in); DefaultDatabaseWriter writer = new DefaultDatabaseWriter(platform, buildDatabaseWriterSettings()); DataProcessor dataProcessor = new DataProcessor(reader, writer, "import"); dataProcessor.process(); } public Format getFormat() { return format; } public void setFormat(Format format) { this.format = format; } public String getCatalog() { return catalog; } public void setCatalog(String catalog) { this.catalog = catalog; } public String getSchema() { return schema; } public void setSchema(String schema) { this.schema = schema; } public void setIgnoreMissingTables(boolean ignoreMissingTables) { this.ignoreMissingTables = ignoreMissingTables; } public boolean isIgnoreMissingTables() { return ignoreMissingTables; } public IDatabasePlatform getPlatform() { return platform; } public void setPlatform(IDatabasePlatform platform) { this.platform = platform; } public boolean isUseVariableDates() { return useVariableDates; } public void setUseVariableForDates(boolean useVariableDates) { this.useVariableDates = useVariableDates; } public void setAlterCaseToMatchDatabaseDefaultCase(boolean alterCaseToMatchDatabaseDefaultCase) { this.alterCaseToMatchDatabaseDefaultCase = alterCaseToMatchDatabaseDefaultCase; } public boolean isAlterCaseToMatchDatabaseDefaultCase() { return alterCaseToMatchDatabaseDefaultCase; } public void setCommitRate(long commitRate) { this.commitRate = commitRate; } public long getCommitRate() { return commitRate; } public void setForceImport(boolean forceImport) { this.forceImport = forceImport; } public boolean isForceImport() { return forceImport; } public void setIgnoreCollisions(boolean ignoreConflicts) { this.ignoreCollisions = ignoreConflicts; } public boolean isIgnoreCollisions() { return ignoreCollisions; } public void setReplaceRows(boolean replaceRows) { this.replaceRows = replaceRows; } public boolean isReplaceRows() { return replaceRows; } public void setAlterTables(boolean alterTables) { this.alterTables = alterTables; } public boolean isAlterTables() { return alterTables; } public void setDropIfExists(boolean dropIfExists) { this.dropIfExists = dropIfExists; } public boolean isDropIfExists() { return dropIfExists; } public void addDatabaseWriterFilter(IDatabaseWriterFilter filter) { databaseWriterFilters.add(filter); } public void removeDatabaseWriterFilter(IDatabaseWriterFilter filter) { databaseWriterFilters.remove(filter); } public int getInterval() { return interval; } public void setInterval(int interval) { this.interval = interval; } }