001: /*
002: * TableCopy.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.LinkedHashMap;
016: import java.util.List;
017: import java.util.Map;
018: import workbench.db.ColumnIdentifier;
019: import workbench.db.TableIdentifier;
020: import workbench.db.WbConnection;
021: import workbench.db.datacopy.DataCopier;
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: import workbench.util.SqlUtil;
029: import workbench.util.StringUtil;
030:
031: /**
032: *
033: * @author support@sql-workbench.net
034: */
035: public class TableCopy implements CopyTask {
036: private WbConnection sourceConnection;
037: private WbConnection targetConnection;
038: private MessageBuffer messages;
039: private DataCopier copier;
040:
041: public TableCopy() {
042: }
043:
044: public void copyData() throws SQLException, Exception {
045: this .copier.startCopy();
046: }
047:
048: public boolean init(WbConnection source, WbConnection target,
049: StatementRunnerResult result, ArgumentParser cmdLine,
050: RowActionMonitor monitor) throws SQLException {
051: this .sourceConnection = source;
052: this .targetConnection = target;
053:
054: String sourcetable = cmdLine.getValue(WbCopy.PARAM_SOURCETABLE);
055: String sourcequery = cmdLine.getValue(WbCopy.PARAM_SOURCEQUERY);
056: String targettable = cmdLine.getValue(WbCopy.PARAM_TARGETTABLE);
057:
058: boolean delete = cmdLine.getBoolean(WbCopy.PARAM_DELETETARGET);
059: boolean cont = cmdLine.getBoolean(CommonArgs.ARG_CONTINUE);
060:
061: boolean createTable = cmdLine
062: .getBoolean(WbCopy.PARAM_CREATETARGET);
063: boolean dropTable = cmdLine.getBoolean(WbCopy.PARAM_DROPTARGET);
064: String keys = cmdLine.getValue(WbCopy.PARAM_KEYS);
065:
066: this .copier = new DataCopier();
067: copier.setTransactionControl(cmdLine.getBoolean(
068: CommonArgs.ARG_TRANS_CONTROL, true));
069: copier.setKeyColumns(keys);
070:
071: String mode = cmdLine.getValue(CommonArgs.ARG_IMPORT_MODE);
072: if (mode != null) {
073: if (!this .copier.setMode(mode)) {
074: result.addMessage(ResourceMgr.getString(
075: "ErrInvalidModeIgnored").replaceAll("%mode%",
076: mode));
077: result.setWarning(true);
078: }
079: }
080:
081: CommonArgs.setProgressInterval(copier, cmdLine);
082: copier.setRowActionMonitor(monitor);
083: copier.setContinueOnError(cont);
084:
085: CommonArgs.setCommitAndBatchParams(copier, cmdLine);
086:
087: copier.setDeleteTarget(delete);
088:
089: TableIdentifier targetId = new TableIdentifier(targettable);
090: targetId.setNewTable(createTable);
091:
092: if (sourcetable != null) {
093: TableIdentifier srcTable = new TableIdentifier(sourcetable);
094: String where = cmdLine.getValue(WbCopy.PARAM_SOURCEWHERE);
095: Map<String, String> mapping = this .parseMapping(cmdLine);
096: copier.copyFromTable(sourceConnection, targetConnection,
097: srcTable, targetId, mapping, where, createTable,
098: dropTable);
099: } else {
100: ColumnIdentifier[] cols = this .parseColumns(cmdLine,
101: sourcequery, sourceConnection);
102: copier
103: .copyFromQuery(sourceConnection, targetConnection,
104: sourcequery, targetId, cols, createTable,
105: dropTable);
106: }
107:
108: return true;
109: }
110:
111: public boolean isSuccess() {
112: if (this .copier == null)
113: return true;
114: return copier.isSuccess();
115: }
116:
117: public CharSequence getMessages() {
118: if (this .copier == null)
119: return null;
120: return copier.getAllMessages();
121: }
122:
123: public void cancel() {
124: if (this .copier != null) {
125: this .copier.cancel();
126: }
127: }
128:
129: private ColumnIdentifier[] parseColumns(ArgumentParser cmdLine,
130: String sourceQuery, WbConnection sourceCon) {
131: // First read the defined columns from the passed parameter
132: String cols = cmdLine.getValue(WbCopy.PARAM_COLUMNS);
133: List l = StringUtil.stringToList(cols, ",");
134: int count = l.size();
135: ColumnIdentifier[] result = new ColumnIdentifier[count];
136: for (int i = 0; i < count; i++) {
137: String c = (String) l.get(i);
138: result[i] = new ColumnIdentifier(c);
139: }
140:
141: // now try to read the column definitions from the query
142: // if a matching column is found, the definition from the query
143: // is used (because it will/should contain the correct datatype information
144: try {
145: List colsFromQuery = SqlUtil.getResultSetColumns(
146: sourceQuery, sourceCon);
147: for (int i = 0; i < count; i++) {
148: int idx = colsFromQuery.indexOf(result[i]);
149: if (idx > -1) {
150: ColumnIdentifier c = (ColumnIdentifier) colsFromQuery
151: .get(idx);
152: result[i] = c;
153: }
154: }
155: } catch (Exception e) {
156: LogMgr
157: .logError(
158: "WbCopy.parseColumns()",
159: "Error retrieving column definition from source query",
160: e);
161: }
162: return result;
163: }
164:
165: private Map<String, String> parseMapping(ArgumentParser cmdLine) {
166: String cols = cmdLine.getValue(WbCopy.PARAM_COLUMNS);
167: if (cols == null || cols.length() == 0)
168: return null;
169:
170: List l = StringUtil.stringToList(cols, ",");
171: int count = l.size();
172:
173: // Use a LinkedHashMap to make sure the order of the columns
174: // are preserved (in case -createTable) was also specified
175: Map<String, String> mapping = new LinkedHashMap<String, String>();
176: for (int i = 0; i < count; i++) {
177: String s = (String) l.get(i);
178: int pos = s.indexOf('/');
179: if (pos == -1) {
180: // No mapping just a list of columns
181: mapping.put(s, null);
182: } else {
183: String scol = s.substring(0, pos).trim();
184: String tcol = s.substring(pos + 1).trim();
185: mapping.put(scol, tcol);
186: }
187: }
188: return mapping;
189: }
190:
191: }
|