1 | /* ============================================================= |
2 | * SmallSQL : a free Java DBMS library for the Java(tm) platform |
3 | * ============================================================= |
4 | * |
5 | * (C) Copyright 2004-2006, by Volker Berlin. |
6 | * |
7 | * Project Info: http://www.smallsql.de/ |
8 | * |
9 | * This library is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU Lesser General Public License as published by |
11 | * the Free Software Foundation; either version 2.1 of the License, or |
12 | * (at your option) any later version. |
13 | * |
14 | * This library is distributed in the hope that it will be useful, but |
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
17 | * License for more details. |
18 | * |
19 | * You should have received a copy of the GNU Lesser General Public |
20 | * License along with this library; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
22 | * USA. |
23 | * |
24 | * [Java is a trademark or registered trademark of Sun Microsystems, Inc. |
25 | * in the United States and other countries.] |
26 | * |
27 | * --------------- |
28 | * SSResultSetMetaData.java |
29 | * --------------- |
30 | * Author: Volker Berlin |
31 | * |
32 | */ |
33 | package smallsql.database; |
34 | |
35 | import java.sql.*; |
36 | |
37 | |
38 | public class SSResultSetMetaData implements ResultSetMetaData { |
39 | |
40 | Expressions columns; |
41 | |
42 | public int getColumnCount() throws SQLException { |
43 | return columns.size(); |
44 | } |
45 | |
46 | |
47 | public boolean isAutoIncrement(int column) throws SQLException { |
48 | return getColumnExpression( column ).isAutoIncrement(); |
49 | } |
50 | |
51 | |
52 | public boolean isCaseSensitive(int column) throws SQLException { |
53 | return getColumnExpression( column ).isCaseSensitive(); |
54 | } |
55 | |
56 | |
57 | public boolean isSearchable(int column) throws SQLException { |
58 | int type = getColumnExpression( column ).getType(); |
59 | return type == Expression.NAME || type == Expression.FUNCTION; |
60 | } |
61 | |
62 | |
63 | public boolean isCurrency(int column) throws SQLException { |
64 | switch(getColumnExpression( column ).getDataType()){ |
65 | case SQLTokenizer.MONEY: |
66 | case SQLTokenizer.SMALLMONEY: |
67 | return true; |
68 | } |
69 | return false; |
70 | } |
71 | |
72 | |
73 | public int isNullable(int column) throws SQLException { |
74 | return getColumnExpression( column ).isNullable() ? columnNullable : columnNoNulls; |
75 | } |
76 | |
77 | |
78 | public boolean isSigned(int column) throws SQLException { |
79 | return isSignedDataType(getColumnExpression( column ).getDataType()); |
80 | } |
81 | |
82 | |
83 | static boolean isSignedDataType(int dataType) { |
84 | switch(dataType){ |
85 | case SQLTokenizer.SMALLINT: |
86 | case SQLTokenizer.INT: |
87 | case SQLTokenizer.BIGINT: |
88 | case SQLTokenizer.SMALLMONEY: |
89 | case SQLTokenizer.MONEY: |
90 | case SQLTokenizer.DECIMAL: |
91 | case SQLTokenizer.NUMERIC: |
92 | case SQLTokenizer.REAL: |
93 | case SQLTokenizer.FLOAT: |
94 | case SQLTokenizer.DOUBLE: |
95 | return true; |
96 | } |
97 | return false; |
98 | } |
99 | |
100 | |
101 | static boolean isNumberDataType(int dataType) { |
102 | return isSignedDataType(dataType) || dataType == SQLTokenizer.TINYINT; |
103 | } |
104 | |
105 | |
106 | static boolean isBinaryDataType(int dataType) { |
107 | switch(dataType){ |
108 | case SQLTokenizer.BINARY: |
109 | case SQLTokenizer.VARBINARY: |
110 | case SQLTokenizer.LONGVARBINARY: |
111 | case SQLTokenizer.BLOB: |
112 | return true; |
113 | } |
114 | return false; |
115 | } |
116 | |
117 | |
118 | static int getDisplaySize(int dataType, int precision, int scale){ |
119 | switch(dataType){ |
120 | case SQLTokenizer.BIT: |
121 | return 1; // 1 and 0 |
122 | case SQLTokenizer.BOOLEAN: |
123 | return 5; //true and false |
124 | case SQLTokenizer.TINYINT: |
125 | return 3; |
126 | case SQLTokenizer.SMALLINT: |
127 | return 6; |
128 | case SQLTokenizer.INT: |
129 | return 10; |
130 | case SQLTokenizer.BIGINT: |
131 | case SQLTokenizer.MONEY: |
132 | return 19; |
133 | case SQLTokenizer.REAL: |
134 | return 13; |
135 | case SQLTokenizer.FLOAT: |
136 | case SQLTokenizer.DOUBLE: |
137 | return 17; |
138 | case SQLTokenizer.LONGVARCHAR: |
139 | case SQLTokenizer.LONGNVARCHAR: |
140 | case SQLTokenizer.LONGVARBINARY: |
141 | case SQLTokenizer.JAVA_OBJECT: |
142 | return Integer.MAX_VALUE; |
143 | case SQLTokenizer.NUMERIC: |
144 | return precision + (scale>0 ? 2 : 1); |
145 | case SQLTokenizer.VARBINARY: |
146 | case SQLTokenizer.BINARY: |
147 | return 2 + precision*2; |
148 | case SQLTokenizer.SMALLDATETIME: |
149 | return 21; |
150 | default: |
151 | return precision; |
152 | } |
153 | } |
154 | |
155 | |
156 | static int getDataTypePrecision(int dataType, int defaultValue){ |
157 | switch(dataType){ |
158 | case SQLTokenizer.NULL: |
159 | return 0; |
160 | case SQLTokenizer.BIT: |
161 | case SQLTokenizer.BOOLEAN: |
162 | return 1; |
163 | case SQLTokenizer.TINYINT: |
164 | return 3; |
165 | case SQLTokenizer.SMALLINT: |
166 | return 5; |
167 | case SQLTokenizer.INT: |
168 | case SQLTokenizer.SMALLMONEY: |
169 | return 10; |
170 | case SQLTokenizer.BIGINT: |
171 | case SQLTokenizer.MONEY: |
172 | return 19; |
173 | case SQLTokenizer.REAL: |
174 | return 7; |
175 | case SQLTokenizer.FLOAT: |
176 | case SQLTokenizer.DOUBLE: |
177 | return 15; |
178 | case SQLTokenizer.CHAR: |
179 | case SQLTokenizer.NCHAR: |
180 | case SQLTokenizer.VARCHAR: |
181 | case SQLTokenizer.NVARCHAR: |
182 | case SQLTokenizer.BINARY: |
183 | case SQLTokenizer.VARBINARY: |
184 | if(defaultValue == -1) |
185 | return 0xFFFF; |
186 | return defaultValue; |
187 | case SQLTokenizer.NUMERIC: |
188 | case SQLTokenizer.DECIMAL: |
189 | return 38; |
190 | case SQLTokenizer.TIMESTAMP: |
191 | return 23; |
192 | case SQLTokenizer.TIME: |
193 | return 8; |
194 | case SQLTokenizer.DATE: |
195 | return 10; |
196 | case SQLTokenizer.SMALLDATETIME: |
197 | return 16; |
198 | case SQLTokenizer.UNIQUEIDENTIFIER: |
199 | return 36; |
200 | case SQLTokenizer.LONGVARCHAR: |
201 | case SQLTokenizer.LONGNVARCHAR: |
202 | case SQLTokenizer.LONGVARBINARY: |
203 | return Integer.MAX_VALUE; |
204 | } |
205 | if(defaultValue == -1) |
206 | throw new Error("Precision:"+SQLTokenizer.getKeyWord(dataType)); |
207 | return defaultValue; |
208 | } |
209 | |
210 | |
211 | public int getColumnDisplaySize(int column) throws SQLException { |
212 | return getColumnExpression( column ).getDisplaySize(); |
213 | } |
214 | public String getColumnLabel(int column) throws SQLException { |
215 | return getColumnExpression( column ).getAlias(); |
216 | } |
217 | public String getColumnName(int column) throws SQLException { |
218 | return getColumnExpression( column ).getAlias(); |
219 | } |
220 | public String getSchemaName(int column) throws SQLException { |
221 | return null; |
222 | } |
223 | public int getPrecision(int column) throws SQLException { |
224 | return getColumnExpression( column ).getPrecision(); |
225 | } |
226 | public int getScale(int column) throws SQLException { |
227 | return getColumnExpression( column ).getScale(); |
228 | } |
229 | public String getTableName(int column) throws SQLException { |
230 | return getColumnExpression( column ).getTableName(); |
231 | } |
232 | public String getCatalogName(int column) throws SQLException { |
233 | return null; |
234 | } |
235 | public int getColumnType(int column) throws SQLException { |
236 | return SQLTokenizer.getSQLDataType(getColumnExpression( column ).getDataType() ); |
237 | } |
238 | public String getColumnTypeName(int column) throws SQLException { |
239 | return SQLTokenizer.getKeyWord( getColumnExpression( column ).getDataType() ); |
240 | } |
241 | public boolean isReadOnly(int column) throws SQLException { |
242 | return !getColumnExpression( column ).isDefinitelyWritable(); |
243 | } |
244 | public boolean isWritable(int column) throws SQLException { |
245 | return getColumnExpression( column ).isDefinitelyWritable(); |
246 | } |
247 | public boolean isDefinitelyWritable(int column) throws SQLException { |
248 | return getColumnExpression( column ).isDefinitelyWritable(); |
249 | } |
250 | public String getColumnClassName(int column) throws SQLException { |
251 | switch(getColumnType(column)){ |
252 | case Types.TINYINT: |
253 | case Types.SMALLINT: |
254 | case Types.INTEGER: |
255 | return "java.lang.Integer"; |
256 | case Types.BIT: |
257 | case Types.BOOLEAN: |
258 | return "java.lang.Boolean"; |
259 | case Types.BINARY: |
260 | case Types.VARBINARY: |
261 | case Types.LONGVARBINARY: |
262 | return "[B"; |
263 | case Types.BLOB: |
264 | return "java.sql.Blob"; |
265 | case Types.BIGINT: |
266 | return "java.lang.Long"; |
267 | case Types.DECIMAL: |
268 | case Types.NUMERIC: |
269 | return "java.math.BigDecimal"; |
270 | case Types.REAL: |
271 | return "java.lang.Float"; |
272 | case Types.FLOAT: |
273 | case Types.DOUBLE: |
274 | return "java.lang.Double"; |
275 | case Types.DATE: |
276 | return "java.sql.Date"; |
277 | case Types.TIME: |
278 | return "java.sql.Time"; |
279 | case Types.TIMESTAMP: |
280 | return "java.sql.Timestamp"; |
281 | case Types.CHAR: |
282 | case Types.VARCHAR: |
283 | case Types.LONGVARCHAR: |
284 | case -11: //uniqueidentifier |
285 | return "java.lang.String"; |
286 | case Types.CLOB: |
287 | return "java.sql.Clob"; |
288 | default: return "java.lang.Object"; |
289 | } |
290 | } |
291 | |
292 | /*======================================================== |
293 | |
294 | private methods |
295 | |
296 | =========================================================*/ |
297 | |
298 | final int getColumnIdx( int column ) throws SQLException{ |
299 | if(column < 1 || column > columns.size()) |
300 | throw new SQLException( "Column index out of range:" + column ); |
301 | return column-1; |
302 | } |
303 | |
304 | final Expression getColumnExpression( int column ) throws SQLException{ |
305 | return columns.get( getColumnIdx( column ) ); |
306 | } |
307 | |
308 | |
309 | } |