001: /*
002: * SchemaCopy.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.sql.wbcommands;
013:
014: import java.sql.SQLException;
015: import java.util.List;
016: import workbench.db.TableIdentifier;
017: import workbench.db.WbConnection;
018: import workbench.db.datacopy.DataCopier;
019: import workbench.db.importer.RowDataReceiver;
020: import workbench.db.importer.TableDependencySorter;
021: import workbench.db.importer.TableStatements;
022: import workbench.log.LogMgr;
023: import workbench.resource.ResourceMgr;
024: import workbench.sql.StatementRunnerResult;
025: import workbench.storage.RowActionMonitor;
026: import workbench.util.ArgumentParser;
027: import workbench.util.MessageBuffer;
028:
029: /**
030: *
031: * @author support@sql-workbench.net
032: */
033: public class SchemaCopy implements CopyTask {
034: private WbConnection sourceConnection;
035: private WbConnection targetConnection;
036: private MessageBuffer messages = new MessageBuffer();
037: private DataCopier copier;
038: private boolean success;
039: private boolean createTable = false;
040: private boolean dropTable = false;
041: private boolean checkDependencies = false;
042:
043: private List<TableIdentifier> sourceTables;
044: private RowActionMonitor rowMonitor;
045: private boolean cancel = false;
046: private ArgumentParser arguments;
047: private String copyMode;
048:
049: public SchemaCopy(List<TableIdentifier> tables) {
050: this .sourceTables = tables;
051: }
052:
053: public void copyData() throws SQLException, Exception {
054: cancel = false;
055:
056: if (this .checkDependencies) {
057: this .sortTables();
058: }
059:
060: int currentTable = 0;
061: int count = sourceTables.size();
062:
063: RowDataReceiver receiver = this .copier.getReceiver();
064: receiver.setTableCount(count);
065:
066: try {
067: copier.beginMultiTableCopy();
068:
069: for (TableIdentifier table : sourceTables) {
070: if (this .cancel) {
071: break;
072: }
073:
074: currentTable++;
075: copier.reset();
076: receiver.setCurrentTable(currentTable);
077:
078: // By creating a new identifier, we are stripping of any schema information
079: // or other source connection specific stuff.
080: TableIdentifier targetTable = new TableIdentifier(table
081: .getTableName());
082: if (!createTable) {
083: // check if the target table exists. DataCopier will throw an exception if
084: // it doesn't but in SchemaCopy we want to simply ignore non-existing tables
085: boolean exists = this .targetConnection
086: .getMetadata().tableExists(targetTable);
087: if (!exists) {
088: this .messages.append(ResourceMgr
089: .getFormattedString(
090: "MsgCopyTableIgnored",
091: targetTable.getTableName()));
092: this .messages.appendNewLine();
093: continue;
094: }
095: }
096: if (messages.getLength() > 0)
097: messages.appendNewLine();
098: this .messages.append(ResourceMgr.getFormattedString(
099: "MsgCopyTable", table.getTableName()));
100: this .messages.appendNewLine();
101:
102: copier.copyFromTable(sourceConnection,
103: targetConnection, table, targetTable, null,
104: null, createTable, dropTable);
105: copier.startCopy();
106:
107: this .messages.append(copier.getMessageBuffer());
108: this .messages.appendNewLine();
109: }
110: this .success = true;
111: } catch (Exception e) {
112: this .success = false;
113: throw e;
114: } finally {
115: copier.endMultiTableCopy();
116: }
117: }
118:
119: private void sortTables() {
120: try {
121: if (this .rowMonitor != null) {
122: this .rowMonitor
123: .setMonitorType(RowActionMonitor.MONITOR_PLAIN);
124: this .rowMonitor.setCurrentObject(ResourceMgr
125: .getString("MsgFkDeps"), -1, -1);
126: }
127: TableDependencySorter sorter = new TableDependencySorter(
128: targetConnection);
129: List<TableIdentifier> sorted = sorter
130: .sortForInsert(sourceTables);
131: if (sorted != null) {
132: this .sourceTables = sorted;
133: }
134: } catch (Exception e) {
135: LogMgr.logError("SchemaCopy.sortTables()",
136: "Error when checking FK dependencies", e);
137: }
138: }
139:
140: public boolean init(WbConnection source, WbConnection target,
141: StatementRunnerResult result, ArgumentParser cmdLine,
142: RowActionMonitor monitor) throws SQLException {
143: this .sourceConnection = source;
144: this .targetConnection = target;
145:
146: this .arguments = cmdLine;
147:
148: boolean deleteTarget = cmdLine
149: .getBoolean(WbCopy.PARAM_DELETETARGET);
150: boolean continueOnError = cmdLine
151: .getBoolean(CommonArgs.ARG_CONTINUE);
152: createTable = cmdLine.getBoolean(WbCopy.PARAM_CREATETARGET);
153: dropTable = cmdLine.getBoolean(WbCopy.PARAM_DROPTARGET);
154:
155: this .copier = new DataCopier();
156: this .rowMonitor = monitor;
157:
158: String mode = cmdLine.getValue(CommonArgs.ARG_IMPORT_MODE);
159: if (mode != null) {
160: if (!this .copier.setMode(mode)) {
161: result.addMessage(ResourceMgr.getString(
162: "ErrInvalidModeIgnored").replaceAll("%mode%",
163: mode));
164: result.setWarning(true);
165: } else {
166: this .copyMode = mode;
167: }
168: }
169:
170: copier.setPerTableStatements(new TableStatements(cmdLine));
171: copier.setTransactionControl(cmdLine.getBoolean(
172: CommonArgs.ARG_TRANS_CONTROL, true));
173:
174: checkDependencies = cmdLine
175: .getBoolean(CommonArgs.ARG_CHECK_FK_DEPS);
176:
177: CommonArgs.setProgressInterval(copier, arguments);
178: CommonArgs.setCommitAndBatchParams(copier, arguments);
179: copier.setContinueOnError(continueOnError);
180: copier.setDeleteTarget(deleteTarget);
181: copier.setRowActionMonitor(rowMonitor);
182: copier.setMode(copyMode);
183:
184: return true;
185: }
186:
187: public boolean isSuccess() {
188: return this .success;
189: }
190:
191: public CharSequence getMessages() {
192: return messages.getBuffer();
193: }
194:
195: public void cancel() {
196: this .cancel = true;
197: if (this.copier != null) {
198: this.copier.cancel();
199: }
200: }
201:
202: }
|