1 /***
2 * Copyright 2004 Steven Caswell
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.mungoknotwise.sqlcli;
17
18 import java.sql.ResultSet;
19 import java.sql.ResultSetMetaData;
20 import java.sql.SQLException;
21 import java.sql.Types;
22 import org.apache.commons.lang.StringUtils;
23 import org.apache.log4j.Logger;
24
25 /***
26 * Implementation of {@link ResultSetExtractor} that writes the result set to
27 * the object's print streams.
28 *
29 * @author Steven Caswell
30 * @version $Id: PrintStreamedResultSetExtractor.java,v 1.1.1.1 2004/07/28 01:12:38 mungoknotwise Exp $
31 */
32 public class PrintStreamedResultSetExtractor
33 extends BasicPrintStreamed
34 implements ResultSetExtractor
35 {
36
37
38
39
40
41 private static Logger logger = Logger.getLogger(PrintStreamedResultSetExtractor.class);
42
43
44
45
46
47
48
49
50
51 private static final int JUSTIFY_LEFT = 1;
52 private static final int JUSTIFY_RIGHT = 2;
53 private static final int MINIMUM_NULL_DISPLAY_SIZE = 4;
54 private static final int TIMESTAMP_DISPLAY_SIZE = 21;
55
56
57
58
59
60
61 private int columnCount;
62 private int[] columnTypes;
63 private int[] displaySizes;
64 private int[] justifys;
65 private String[] labels;
66 private String headerSeparator = "+";
67 private String fieldSeparator = "|";
68
69
70
71
72
73 /***
74 * Constructs a new instance of
75 * <code>PrintStreamedResultSetExtractor</code>.
76 */
77 public PrintStreamedResultSetExtractor()
78 {
79 }
80
81
82
83
84
85
86
87
88 /***
89 * {@inheritDoc}
90 */
91 public Object extractData(final ResultSet resultSet) throws SQLException
92 {
93 ResultSetMetaData metaData = resultSet.getMetaData();
94 this.columnCount = metaData.getColumnCount();
95 this.configureOutput(metaData);
96 this.println("");
97
98 int rowCount = 0;
99 if(this.columnCount > 0)
100 {
101
102 this.writeHeader();
103
104
105 while(resultSet.next())
106 {
107 ++rowCount;
108 for(int i = 1; i <= this.columnCount; i++)
109 {
110 this.print(this.getFieldSeparator());
111 int displaySize = this.displaySizes[i-1];
112 switch(this.columnTypes[i-1])
113 {
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 case Types.ARRAY:
130 case Types.BINARY:
131 case Types.BLOB:
132 case Types.CLOB:
133 case Types.DATALINK:
134 case Types.DISTINCT:
135 case Types.JAVA_OBJECT:
136 case Types.LONGVARBINARY:
137 case Types.LONGVARCHAR:
138 case Types.NULL:
139 case Types.OTHER:
140 case Types.REF:
141 case Types.STRUCT:
142 case Types.VARBINARY:
143 {
144 this.print(StringUtils.rightPad(" ", displaySize));
145 break;
146 }
147 default:
148 {
149 Object value = resultSet.getObject(i);
150 if(resultSet.wasNull())
151 {
152 if(displaySize >= MINIMUM_NULL_DISPLAY_SIZE)
153 {
154 this.print(StringUtils.rightPad("NULL", displaySize));
155 }
156 else
157 {
158 this.print(StringUtils.repeat(" ", displaySize));
159 }
160 }
161 else
162 {
163 if(this.justifys[i-1] == JUSTIFY_LEFT)
164 {
165 this.print(StringUtils.rightPad(value.toString(), displaySize));
166 }
167 else
168 {
169 this.print(StringUtils.leftPad(value.toString(), displaySize));
170 }
171 }
172 }
173 }
174 }
175 this.println(this.getFieldSeparator());
176 }
177
178 this.writeFooter();
179 }
180 this.println(rowCount + " row(s)");
181 this.println("");
182
183 return null;
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210 private void configureOutput(final ResultSetMetaData metaData) throws SQLException
211 {
212 this.displaySizes = new int[this.columnCount];
213 this.justifys = new int[this.columnCount];
214 this.labels = new String[this.columnCount];
215 this.columnTypes = new int[this.columnCount];
216 for(int i = 1; i <= this.columnCount; i++)
217 {
218 int columnType = metaData.getColumnType(i);
219 this.columnTypes[i-1] = columnType;
220
221 String label = metaData.getColumnLabel(i);
222 this.labels[i-1] = label;
223
224 int displaySize = metaData.getColumnDisplaySize(i);
225 if(columnType == Types.TIMESTAMP)
226 {
227 displaySize = TIMESTAMP_DISPLAY_SIZE;
228 }
229 this.displaySizes[i-1] = (displaySize > label.length() ? displaySize : label.length());
230
231 this.justifys[i-1] = JUSTIFY_LEFT;
232 switch(columnType)
233 {
234 case Types.BIGINT:
235 case Types.DECIMAL:
236 case Types.DOUBLE:
237 case Types.FLOAT:
238 case Types.INTEGER:
239 case Types.NUMERIC:
240 case Types.REAL:
241 case Types.SMALLINT:
242 {
243 this.justifys[i-1] = JUSTIFY_RIGHT;
244 break;
245 }
246 default:
247 {
248 this.justifys[i-1] = JUSTIFY_LEFT;
249 break;
250 }
251 }
252
253 String columnTypeName = metaData.getColumnTypeName(i);
254 }
255 }
256
257 private void writeFooter()
258 {
259 this.writeHeaderLine();
260 this.println("");
261 }
262
263 private void writeHeader()
264 {
265 this.writeHeaderLine();
266
267 for(int i = 1; i <= columnCount; i++)
268 {
269 this.print(this.getFieldSeparator());
270
271 this.print(StringUtils.rightPad(this.labels[i-1], this.displaySizes[i-1]));
272 }
273 this.println(this.getFieldSeparator());
274
275 this.writeHeaderLine();
276 }
277
278 private void writeHeaderLine()
279 {
280 for(int i = 1; i <= this.columnCount; i++)
281 {
282 this.print(this.getHeaderSeparator());
283 this.print(StringUtils.repeat("-", this.displaySizes[i-1]));
284 }
285 this.println(this.getHeaderSeparator());
286 }
287
288 private String getFieldSeparator()
289 {
290 return this.fieldSeparator;
291 }
292
293 private String getHeaderSeparator()
294 {
295 return this.headerSeparator;
296 }
297
298
299
300
301
302 }