1 | /* |
2 | |
3 | Derby - Class org.apache.derby.impl.jdbc.EmbedResultSetMetaData |
4 | |
5 | Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.impl.jdbc; |
22 | |
23 | import org.apache.derby.iapi.sql.ResultDescription; |
24 | import org.apache.derby.iapi.sql.ResultColumnDescriptor; |
25 | import org.apache.derby.iapi.types.DataTypeDescriptor; |
26 | import org.apache.derby.iapi.types.DataTypeUtilities; |
27 | import org.apache.derby.iapi.types.TypeId; |
28 | |
29 | import org.apache.derby.iapi.services.sanity.SanityManager; |
30 | |
31 | import org.apache.derby.iapi.reference.SQLState; |
32 | |
33 | import java.sql.ResultSetMetaData; |
34 | import java.sql.SQLException; |
35 | import java.sql.Types; |
36 | import java.sql.ResultSet; |
37 | |
38 | /** |
39 | * A ResultSetMetaData object can be used to find out about the types |
40 | * and properties of the columns in a ResultSet. |
41 | * |
42 | * <p> |
43 | * We take the (cloudscape) ResultDescription and examine it, to return |
44 | * the appropriate information. |
45 | |
46 | <P> |
47 | This class can be used outside of this package to convert a |
48 | ResultDescription into a ResultSetMetaData object. |
49 | * |
50 | * @author ames |
51 | */ |
52 | public class EmbedResultSetMetaData |
53 | implements ResultSetMetaData { |
54 | |
55 | private final ResultColumnDescriptor[] columnInfo; |
56 | |
57 | // |
58 | // constructor |
59 | // |
60 | public EmbedResultSetMetaData(ResultColumnDescriptor[] columnInfo) { |
61 | this.columnInfo = columnInfo; |
62 | } |
63 | |
64 | // |
65 | // ResultSetMetaData interface |
66 | // |
67 | |
68 | /** |
69 | * What's the number of columns in the ResultSet? |
70 | * |
71 | * @return the number |
72 | */ |
73 | public int getColumnCount() { |
74 | return columnInfo == null ? 0 : columnInfo.length; |
75 | } |
76 | |
77 | /** |
78 | * Is the column automatically numbered, thus read-only? |
79 | * |
80 | * @param column the first column is 1, the second is 2, ... |
81 | * @return true if so |
82 | * @exception SQLException thrown on failure |
83 | * |
84 | */ |
85 | public boolean isAutoIncrement(int column) throws SQLException { |
86 | |
87 | ResultColumnDescriptor rcd = columnInfo[column - 1]; |
88 | return rcd.isAutoincrement(); |
89 | } |
90 | |
91 | /** |
92 | * Does a column's case matter? |
93 | * |
94 | * @param column the first column is 1, the second is 2, ... |
95 | * @return true if so |
96 | * @exception SQLException thrown on failure |
97 | */ |
98 | public boolean isCaseSensitive(int column) throws SQLException { |
99 | return DataTypeUtilities.isCaseSensitive(getColumnTypeDescriptor(column)); |
100 | } |
101 | |
102 | |
103 | /** |
104 | * Can the column be used in a where clause? |
105 | * |
106 | * @param column the first column is 1, the second is 2, ... |
107 | * @return true if so |
108 | * @exception SQLException thrown on failure |
109 | */ |
110 | public boolean isSearchable(int column) throws SQLException { |
111 | validColumnNumber(column); |
112 | |
113 | // we have no restrictions yet, so this is always true |
114 | // might eventually be false for e.g. extra-long columns? |
115 | return true; |
116 | } |
117 | |
118 | /** |
119 | * Is the column a cash value? |
120 | * |
121 | * @param column the first column is 1, the second is 2, ... |
122 | * @return true if so |
123 | * @exception SQLException thrown on failure |
124 | */ |
125 | public boolean isCurrency(int column) throws SQLException { |
126 | |
127 | return DataTypeUtilities.isCurrency(getColumnTypeDescriptor(column)); |
128 | } |
129 | |
130 | /** |
131 | * Can you put a NULL in this column? |
132 | * |
133 | * @param column the first column is 1, the second is 2, ... |
134 | * @return columnNoNulls, columnNullable or columnNullableUnknown |
135 | * @exception SQLException thrown on failure |
136 | */ |
137 | public int isNullable(int column) throws SQLException { |
138 | return DataTypeUtilities.isNullable(getColumnTypeDescriptor(column)); |
139 | } |
140 | |
141 | /** |
142 | * Is the column a signed number? |
143 | * |
144 | * @param column the first column is 1, the second is 2, ... |
145 | * @return true if so |
146 | * @exception SQLException thrown on failure |
147 | */ |
148 | public boolean isSigned(int column) throws SQLException { |
149 | return DataTypeUtilities.isSigned(getColumnTypeDescriptor(column)); |
150 | } |
151 | |
152 | |
153 | /** |
154 | * What's the column's normal max width in chars? |
155 | * |
156 | * @param column the first column is 1, the second is 2, ... |
157 | * @return max width |
158 | * @exception SQLException thrown on failure |
159 | */ |
160 | public int getColumnDisplaySize(int column) throws SQLException { |
161 | return DataTypeUtilities.getColumnDisplaySize(getColumnTypeDescriptor(column)); |
162 | } |
163 | |
164 | /** |
165 | * What's the suggested column title for use in printouts and |
166 | * displays? |
167 | * |
168 | * @param column the first column is 1, the second is 2, ... |
169 | * @return true if so |
170 | * @exception SQLException thrown on failure |
171 | */ |
172 | public String getColumnLabel(int column) throws SQLException { |
173 | ResultColumnDescriptor cd = columnInfo[column - 1]; |
174 | String s = cd.getName(); |
175 | |
176 | // we could get fancier than this, but it's simple |
177 | return (s==null? "Column"+Integer.toString(column) : s); |
178 | } |
179 | |
180 | |
181 | /** |
182 | * What's a column's name? |
183 | * |
184 | * @param column the first column is 1, the second is 2, ... |
185 | * @return column name |
186 | * @exception SQLException thrown on failure |
187 | */ |
188 | public String getColumnName(int column) throws SQLException { |
189 | ResultColumnDescriptor cd = columnInfo[column - 1]; |
190 | String s = cd.getName(); |
191 | // database returns null when no column name to differentiate from empty name |
192 | return (s==null? "" : s); |
193 | |
194 | } |
195 | |
196 | |
197 | /** |
198 | * What's a column's table's schema? |
199 | * |
200 | * @param column the first column is 1, the second is 2, ... |
201 | * @return schema name or "" if not applicable |
202 | * @exception SQLException thrown on failure |
203 | */ |
204 | public String getSchemaName(int column) throws SQLException { |
205 | ResultColumnDescriptor cd = columnInfo[column - 1]; |
206 | |
207 | String s = cd.getSourceSchemaName(); |
208 | // database returns null when no schema name to differentiate from empty name |
209 | return (s==null? "" : s); |
210 | } |
211 | |
212 | /** |
213 | * What's a column's number of decimal digits? |
214 | * |
215 | * @param column the first column is 1, the second is 2, ... |
216 | * @return precision |
217 | * @exception SQLException thrown on failure |
218 | */ |
219 | public int getPrecision(int column) throws SQLException { |
220 | return DataTypeUtilities.getDigitPrecision(getColumnTypeDescriptor(column)); |
221 | } |
222 | |
223 | |
224 | /** |
225 | * What's a column's number of digits to right of the decimal point? |
226 | * |
227 | * @param column the first column is 1, the second is 2, ... |
228 | * @return scale |
229 | * @exception SQLException thrown on failure |
230 | */ |
231 | public int getScale(int column) throws SQLException { |
232 | DataTypeDescriptor dtd = getColumnTypeDescriptor(column); |
233 | // REMIND -- check it is valid to ask for scale |
234 | return dtd.getScale(); |
235 | } |
236 | |
237 | /** |
238 | * What's a column's table name? |
239 | * |
240 | * @return table name or "" if not applicable |
241 | * @exception SQLException thrown on failure |
242 | */ |
243 | public String getTableName(int column) throws SQLException { |
244 | ResultColumnDescriptor cd = columnInfo[column - 1]; |
245 | String s = cd.getSourceTableName(); |
246 | |
247 | // database returns null when no table name to differentiate from empty name |
248 | return (s==null? "" : s); |
249 | } |
250 | |
251 | /** |
252 | * What's a column's table's catalog name? |
253 | * |
254 | * @param column the first column is 1, the second is 2, ... |
255 | * @return column name or "" if not applicable. |
256 | * @exception SQLException thrown on failure |
257 | */ |
258 | public String getCatalogName(int column) throws SQLException { |
259 | validColumnNumber(column); |
260 | return ""; |
261 | } |
262 | |
263 | /** |
264 | * What's a column's SQL type? |
265 | * |
266 | * @param column the first column is 1, the second is 2, ... |
267 | * @return SQL type |
268 | * @see Types |
269 | * @exception SQLException thrown on failure |
270 | */ |
271 | public int getColumnType(int column) throws SQLException { |
272 | DataTypeDescriptor dtd = getColumnTypeDescriptor(column); |
273 | return dtd.getTypeId().getJDBCTypeId(); |
274 | } |
275 | |
276 | /** |
277 | * What's a column's data source specific type name? |
278 | * |
279 | * @param column the first column is 1, the second is 2, ... |
280 | * @return type name |
281 | * @exception SQLException thrown on failure |
282 | */ |
283 | public String getColumnTypeName(int column) throws SQLException { |
284 | DataTypeDescriptor dtd = getColumnTypeDescriptor(column); |
285 | return dtd.getTypeId().getSQLTypeName(); |
286 | } |
287 | |
288 | /** |
289 | * Is a column definitely not writable? |
290 | * |
291 | * @param column the first column is 1, the second is 2, ... |
292 | * @return true if so |
293 | * @exception SQLException thrown on failure |
294 | */ |
295 | public boolean isReadOnly(int column) throws SQLException { |
296 | validColumnNumber(column); |
297 | |
298 | // we just don't know if it is a base table column or not |
299 | return false; |
300 | } |
301 | |
302 | /** |
303 | * Is it possible for a write on the column to succeed? |
304 | * |
305 | * @param column the first column is 1, the second is 2, ... |
306 | * @return true if so |
307 | * @exception SQLException thrown on failure |
308 | */ |
309 | public boolean isWritable(int column) throws SQLException { |
310 | validColumnNumber(column); |
311 | return columnInfo[column - 1].updatableByCursor(); |
312 | } |
313 | |
314 | /** |
315 | * Will a write on the column definitely succeed? |
316 | * |
317 | * @param column the first column is 1, the second is 2, ... |
318 | * @return true if so |
319 | * @exception SQLException thrown on failure |
320 | */ |
321 | public boolean isDefinitelyWritable(int column) throws SQLException { |
322 | validColumnNumber(column); |
323 | |
324 | // we just don't know if it is a base table column or not |
325 | return false; |
326 | } |
327 | |
328 | /* |
329 | * class interface |
330 | */ |
331 | |
332 | private void validColumnNumber(int column) throws SQLException { |
333 | if (column < 1 || |
334 | column > getColumnCount() ) |
335 | throw Util.generateCsSQLException( |
336 | SQLState.COLUMN_NOT_FOUND, new Integer(column)); |
337 | } |
338 | |
339 | public DataTypeDescriptor getColumnTypeDescriptor(int column) throws SQLException |
340 | { |
341 | validColumnNumber(column); |
342 | |
343 | ResultColumnDescriptor cd = columnInfo[column - 1]; |
344 | |
345 | return cd.getType(); |
346 | } |
347 | |
348 | ///////////////////////////////////////////////////////////////////////// |
349 | // |
350 | // JDBC 2.0 - New public methods |
351 | // |
352 | ///////////////////////////////////////////////////////////////////////// |
353 | |
354 | /** |
355 | * JDBC 2.0 |
356 | * |
357 | * <p>Return the fully qualified name of the Java class whose instances |
358 | * are manufactured if ResultSet.getObject() is called to retrieve a value |
359 | * from the column. ResultSet.getObject() may return a subClass of the |
360 | * class returned by this method. |
361 | * |
362 | * @exception SQLException Feature not inplemented for now. |
363 | */ |
364 | public String getColumnClassName(int column) throws SQLException { |
365 | |
366 | return getColumnTypeDescriptor(column).getTypeId().getResultSetMetaDataTypeName(); |
367 | } |
368 | |
369 | |
370 | public static ResultColumnDescriptor getResultColumnDescriptor(String name, int jdcbTypeId, boolean nullable) { |
371 | |
372 | return new org.apache.derby.impl.sql.GenericColumnDescriptor( |
373 | name, DataTypeDescriptor.getBuiltInDataTypeDescriptor(jdcbTypeId, nullable)); |
374 | } |
375 | public static ResultColumnDescriptor getResultColumnDescriptor(String name, int jdcbTypeId, boolean nullable, int length) { |
376 | |
377 | return new org.apache.derby.impl.sql.GenericColumnDescriptor( |
378 | name, DataTypeDescriptor.getBuiltInDataTypeDescriptor(jdcbTypeId, nullable, length)); |
379 | } |
380 | public static ResultColumnDescriptor getResultColumnDescriptor(String name, DataTypeDescriptor dtd) { |
381 | return new org.apache.derby.impl.sql.GenericColumnDescriptor(name, dtd); |
382 | } |
383 | } |