1 | /* |
2 | * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, |
3 | * and the EPL 1.0 (http://h2database.com/html/license.html). |
4 | * Initial Developer: H2 Group |
5 | */ |
6 | package org.h2.jdbc; |
7 | |
8 | import java.sql.ParameterMetaData; |
9 | import java.sql.SQLException; |
10 | import java.util.ArrayList; |
11 | import org.h2.command.CommandInterface; |
12 | import org.h2.expression.ParameterInterface; |
13 | import org.h2.message.DbException; |
14 | import org.h2.message.Trace; |
15 | import org.h2.message.TraceObject; |
16 | import org.h2.util.MathUtils; |
17 | import org.h2.value.DataType; |
18 | import org.h2.value.Value; |
19 | |
20 | /** |
21 | * Information about the parameters of a prepared statement. |
22 | */ |
23 | public class JdbcParameterMetaData extends TraceObject implements |
24 | ParameterMetaData { |
25 | |
26 | private final JdbcPreparedStatement prep; |
27 | private final int paramCount; |
28 | private final ArrayList<? extends ParameterInterface> parameters; |
29 | |
30 | JdbcParameterMetaData(Trace trace, JdbcPreparedStatement prep, |
31 | CommandInterface command, int id) { |
32 | setTrace(trace, TraceObject.PARAMETER_META_DATA, id); |
33 | this.prep = prep; |
34 | this.parameters = command.getParameters(); |
35 | this.paramCount = parameters.size(); |
36 | } |
37 | |
38 | /** |
39 | * Returns the number of parameters. |
40 | * |
41 | * @return the number |
42 | */ |
43 | @Override |
44 | public int getParameterCount() throws SQLException { |
45 | try { |
46 | debugCodeCall("getParameterCount"); |
47 | checkClosed(); |
48 | return paramCount; |
49 | } catch (Exception e) { |
50 | throw logAndConvert(e); |
51 | } |
52 | } |
53 | |
54 | /** |
55 | * Returns the parameter mode. |
56 | * Always returns parameterModeIn. |
57 | * |
58 | * @param param the column index (1,2,...) |
59 | * @return parameterModeIn |
60 | */ |
61 | @Override |
62 | public int getParameterMode(int param) throws SQLException { |
63 | try { |
64 | debugCodeCall("getParameterMode", param); |
65 | getParameter(param); |
66 | return parameterModeIn; |
67 | } catch (Exception e) { |
68 | throw logAndConvert(e); |
69 | } |
70 | } |
71 | |
72 | /** |
73 | * Returns the parameter type. |
74 | * java.sql.Types.VARCHAR is returned if the data type is not known. |
75 | * |
76 | * @param param the column index (1,2,...) |
77 | * @return the data type |
78 | */ |
79 | @Override |
80 | public int getParameterType(int param) throws SQLException { |
81 | try { |
82 | debugCodeCall("getParameterType", param); |
83 | ParameterInterface p = getParameter(param); |
84 | int type = p.getType(); |
85 | if (type == Value.UNKNOWN) { |
86 | type = Value.STRING; |
87 | } |
88 | return DataType.getDataType(type).sqlType; |
89 | } catch (Exception e) { |
90 | throw logAndConvert(e); |
91 | } |
92 | } |
93 | |
94 | /** |
95 | * Returns the parameter precision. |
96 | * The value 0 is returned if the precision is not known. |
97 | * |
98 | * @param param the column index (1,2,...) |
99 | * @return the precision |
100 | */ |
101 | @Override |
102 | public int getPrecision(int param) throws SQLException { |
103 | try { |
104 | debugCodeCall("getPrecision", param); |
105 | ParameterInterface p = getParameter(param); |
106 | return MathUtils.convertLongToInt(p.getPrecision()); |
107 | } catch (Exception e) { |
108 | throw logAndConvert(e); |
109 | } |
110 | } |
111 | |
112 | /** |
113 | * Returns the parameter scale. |
114 | * The value 0 is returned if the scale is not known. |
115 | * |
116 | * @param param the column index (1,2,...) |
117 | * @return the scale |
118 | */ |
119 | @Override |
120 | public int getScale(int param) throws SQLException { |
121 | try { |
122 | debugCodeCall("getScale", param); |
123 | ParameterInterface p = getParameter(param); |
124 | return p.getScale(); |
125 | } catch (Exception e) { |
126 | throw logAndConvert(e); |
127 | } |
128 | } |
129 | |
130 | /** |
131 | * Checks if this is nullable parameter. |
132 | * Returns ResultSetMetaData.columnNullableUnknown.. |
133 | * |
134 | * @param param the column index (1,2,...) |
135 | * @return ResultSetMetaData.columnNullableUnknown |
136 | */ |
137 | @Override |
138 | public int isNullable(int param) throws SQLException { |
139 | try { |
140 | debugCodeCall("isNullable", param); |
141 | return getParameter(param).getNullable(); |
142 | } catch (Exception e) { |
143 | throw logAndConvert(e); |
144 | } |
145 | } |
146 | |
147 | /** |
148 | * Checks if this parameter is signed. |
149 | * It always returns true. |
150 | * |
151 | * @param param the column index (1,2,...) |
152 | * @return true |
153 | */ |
154 | @Override |
155 | public boolean isSigned(int param) throws SQLException { |
156 | try { |
157 | debugCodeCall("isSigned", param); |
158 | getParameter(param); |
159 | return true; |
160 | } catch (Exception e) { |
161 | throw logAndConvert(e); |
162 | } |
163 | } |
164 | |
165 | /** |
166 | * Returns the Java class name of the parameter. |
167 | * "java.lang.String" is returned if the type is not known. |
168 | * |
169 | * @param param the column index (1,2,...) |
170 | * @return the Java class name |
171 | */ |
172 | @Override |
173 | public String getParameterClassName(int param) throws SQLException { |
174 | try { |
175 | debugCodeCall("getParameterClassName", param); |
176 | ParameterInterface p = getParameter(param); |
177 | int type = p.getType(); |
178 | if (type == Value.UNKNOWN) { |
179 | type = Value.STRING; |
180 | } |
181 | return DataType.getTypeClassName(type); |
182 | } catch (Exception e) { |
183 | throw logAndConvert(e); |
184 | } |
185 | } |
186 | |
187 | /** |
188 | * Returns the parameter type name. |
189 | * "VARCHAR" is returned if the type is not known. |
190 | * |
191 | * @param param the column index (1,2,...) |
192 | * @return the type name |
193 | */ |
194 | @Override |
195 | public String getParameterTypeName(int param) throws SQLException { |
196 | try { |
197 | debugCodeCall("getParameterTypeName", param); |
198 | ParameterInterface p = getParameter(param); |
199 | int type = p.getType(); |
200 | if (type == Value.UNKNOWN) { |
201 | type = Value.STRING; |
202 | } |
203 | return DataType.getDataType(type).name; |
204 | } catch (Exception e) { |
205 | throw logAndConvert(e); |
206 | } |
207 | } |
208 | |
209 | private ParameterInterface getParameter(int param) { |
210 | checkClosed(); |
211 | if (param < 1 || param > paramCount) { |
212 | throw DbException.getInvalidValueException("param", param); |
213 | } |
214 | return parameters.get(param - 1); |
215 | } |
216 | |
217 | private void checkClosed() { |
218 | prep.checkClosed(); |
219 | } |
220 | |
221 | /** |
222 | * Return an object of this class if possible. |
223 | * |
224 | * @param iface the class |
225 | * @return this |
226 | */ |
227 | @Override |
228 | @SuppressWarnings("unchecked") |
229 | public <T> T unwrap(Class<T> iface) throws SQLException { |
230 | if (isWrapperFor(iface)) { |
231 | return (T) this; |
232 | } |
233 | throw DbException.getInvalidValueException("iface", iface); |
234 | } |
235 | |
236 | /** |
237 | * Checks if unwrap can return an object of this class. |
238 | * |
239 | * @param iface the class |
240 | * @return whether or not the interface is assignable from this class |
241 | */ |
242 | @Override |
243 | public boolean isWrapperFor(Class<?> iface) throws SQLException { |
244 | return iface != null && iface.isAssignableFrom(getClass()); |
245 | } |
246 | |
247 | /** |
248 | * INTERNAL |
249 | */ |
250 | @Override |
251 | public String toString() { |
252 | return getTraceObjectName() + ": parameterCount=" + paramCount; |
253 | } |
254 | |
255 | } |