001: /*
002: * ExportWriter.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.db.exporter;
013:
014: import java.io.File;
015: import java.io.IOException;
016: import java.io.Writer;
017: import java.sql.ResultSet;
018: import java.sql.SQLException;
019: import java.util.Set;
020: import workbench.log.LogMgr;
021: import workbench.storage.DataStore;
022:
023: import workbench.storage.ResultInfo;
024: import workbench.storage.RowActionMonitor;
025: import workbench.storage.RowData;
026: import workbench.util.FileUtil;
027: import workbench.util.StrBuffer;
028: import workbench.util.WbFile;
029:
030: /**
031: *
032: * @author support@sql-workbench.net
033: */
034: public abstract class ExportWriter {
035: protected DataExporter exporter;
036: protected boolean cancel = false;
037: protected long rows;
038: protected String tableToUse;
039: protected RowActionMonitor rowMonitor;
040: protected RowDataConverter converter;
041: protected Writer outputWriter;
042: protected WbFile outputFile;
043: private int progressInterval = 10;
044:
045: public ExportWriter(DataExporter exp) {
046: this .exporter = exp;
047: converter = createConverter();
048: // configureConverter() might be called more than once
049: // to prevent connection dependent information to be read
050: // more than once, call setOriginalConnection() only
051: // here and now
052: converter.setOriginalConnection(this .exporter.getConnection());
053: configureConverter();
054: }
055:
056: public void configureConverter() {
057: converter.setErrorReporter(exporter);
058: converter.setEncoding(exporter.getEncoding());
059: converter.setDefaultDateFormatter(exporter.getDateFormatter());
060: converter.setDefaultTimestampFormatter(exporter
061: .getTimestampFormatter());
062: converter.setDefaultNumberFormatter(exporter
063: .getDecimalFormatter());
064: converter
065: .setColumnsToExport(this .exporter.getColumnsToExport());
066: converter
067: .setCompressExternalFiles(exporter.getCompressOutput());
068: converter.setBlobIdColumns(exporter.getBlobIdColumns());
069: converter.setFilenameColumn(exporter.getFilenameColumn());
070: converter.setPageTitle(exporter.getPageTitle());
071: converter.setWriteHeader(exporter.getExportHeaders());
072:
073: String file = this .exporter.getOutputFilename();
074: if (file != null)
075: converter.setOutputFile(new File(file));
076: }
077:
078: public abstract RowDataConverter createConverter();
079:
080: public void setProgressInterval(int interval) {
081: if (interval <= 0)
082: this .progressInterval = 0;
083: else
084: this .progressInterval = interval;
085: }
086:
087: public void setRowMonitor(RowActionMonitor monitor) {
088: this .rowMonitor = monitor;
089: }
090:
091: public long getNumberOfRecords() {
092: return rows;
093: }
094:
095: public void writeExport(DataStore ds) throws SQLException,
096: IOException {
097: ResultInfo info = ds.getResultInfo();
098: this .converter.setGeneratingSql(exporter.getSql());
099: this .converter.setResultInfo(info);
100:
101: if (this .converter.needsUpdateTable()) {
102: ds.checkUpdateTable();
103: }
104:
105: this .cancel = false;
106: this .rows = 0;
107:
108: if (this .rowMonitor != null && this .progressInterval > 0) {
109: this .rowMonitor
110: .setMonitorType(RowActionMonitor.MONITOR_EXPORT);
111: }
112:
113: writeStart();
114:
115: int rowCount = ds.getRowCount();
116: for (int i = 0; i < rowCount; i++) {
117: if (this .cancel)
118: break;
119:
120: if (this .rowMonitor != null
121: && this .progressInterval > 0
122: && (this .rows == 1 || this .rows
123: % this .progressInterval == 0)) {
124: this .rowMonitor.setCurrentRow((int) this .rows, -1);
125: }
126: RowData row = ds.getRow(i);
127: writeRow(row, rows);
128: rows++;
129: }
130: writeEnd(rows);
131: }
132:
133: public boolean managesOutput() {
134: return false;
135: }
136:
137: public void setOutputFile(WbFile out) {
138: this .outputWriter = null;
139: this .outputFile = out;
140: }
141:
142: public void setOutputWriter(Writer out) {
143: this .outputWriter = out;
144: this .outputFile = null;
145: }
146:
147: public void writeExport(ResultSet rs, ResultInfo info)
148: throws SQLException, IOException {
149: this .converter.setResultInfo(info);
150: this .converter.setGeneratingSql(exporter.getSql());
151:
152: this .cancel = false;
153: this .rows = 0;
154:
155: if (this .rowMonitor != null && this .progressInterval > 0) {
156: this .rowMonitor
157: .setMonitorType(RowActionMonitor.MONITOR_EXPORT);
158: }
159: int colCount = info.getColumnCount();
160:
161: if (!this .exporter.getAppendToFile())
162: writeStart();
163: while (rs.next()) {
164: if (this .cancel)
165: break;
166:
167: if (this .rowMonitor != null
168: && this .progressInterval > 0
169: && (this .rows == 1 || this .rows
170: % this .progressInterval == 0)) {
171: this .rowMonitor.setCurrentRow((int) this .rows, -1);
172: }
173: RowData row = new RowData(colCount);
174: row.read(rs, info);
175: writeRow(row, rows);
176: rows++;
177: }
178: writeEnd(rows);
179: }
180:
181: protected void writeRow(RowData row, long numRows)
182: throws IOException {
183: StrBuffer data = converter.convertRowData(row, numRows);
184: if (data != null && outputWriter != null) {
185: data.writeTo(this .outputWriter);
186: }
187: }
188:
189: protected void writeStart() throws IOException {
190: writeFormatFile();
191: StrBuffer data = converter.getStart();
192: if (data != null && outputWriter != null) {
193: data.writeTo(this .outputWriter);
194: }
195: }
196:
197: protected void writeEnd(long totalRows) throws IOException {
198: StrBuffer data = converter.getEnd(totalRows);
199: if (data != null && outputWriter != null) {
200: data.writeTo(this .outputWriter);
201: }
202: }
203:
204: public void exportStarting() throws IOException {
205:
206: }
207:
208: public void exportFinished() {
209: FileUtil.closeQuitely(outputWriter);
210: try {
211: if (this .converter != null)
212: this .converter.exportFinished();
213: } catch (Exception e) {
214: LogMgr.logError("ExportWriter.exportFinished()",
215: "Error closing output stream", e);
216: }
217:
218: }
219:
220: public void cancel() {
221: this .cancel = true;
222: }
223:
224: /**
225: * Getter for property tableToUse.
226: * @return Value of property tableToUse.
227: */
228: public String getTableToUse() {
229: return tableToUse;
230: }
231:
232: /**
233: * Setter for property tableToUse.
234: * @param tableToUse New value of property tableToUse.
235: */
236: public void setTableToUse(String tableToUse) {
237: this .tableToUse = tableToUse;
238: }
239:
240: protected void writeFormatFile() {
241: Set<ControlFileFormat> formats = exporter
242: .getControlFileFormats();
243: for (ControlFileFormat format : formats) {
244: FormatFileWriter writer = ControlFileFormat
245: .createFormatWriter(format);
246: writer.writeFormatFile(exporter, converter);
247: }
248: }
249: }
|