KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > GenericParameterValueSet


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.GenericParameterValueSet
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.sql;
23
24 import org.apache.derby.iapi.services.loader.ClassFactory;
25 import org.apache.derby.iapi.services.loader.ClassInspector;
26 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
27
28 import org.apache.derby.iapi.sql.ParameterValueSet;
29
30 import org.apache.derby.iapi.types.DataTypeDescriptor;
31 import org.apache.derby.iapi.types.DataValueFactory;
32 import org.apache.derby.iapi.types.DataValueDescriptor;
33 import org.apache.derby.iapi.types.UserDataValue;
34
35 import org.apache.derby.iapi.reference.SQLState;
36
37 import org.apache.derby.iapi.error.StandardException;
38
39 import org.apache.derby.iapi.services.sanity.SanityManager;
40
41 import java.io.InputStream JavaDoc;
42 import java.sql.Date JavaDoc;
43 import java.sql.Time JavaDoc;
44 import java.sql.Timestamp JavaDoc;
45 import java.sql.Types JavaDoc;
46 import org.apache.derby.iapi.reference.JDBC30Translation;
47
48 /**
49  * Implementation of ParameterValueSet
50  *
51  * @see ParameterValueSet
52  *
53  * @author Jeff Lichtman
54  */

55
56 final class GenericParameterValueSet implements ParameterValueSet
57 {
58   //all this has to be copied in the clone constructor
59
private final GenericParameter[] parms;
60     final ClassInspector ci;
61     private final boolean hasReturnOutputParam;
62
63
64     /**
65      * Constructor for a GenericParameterValueSet
66      *
67      * @param numParms The number of parameters in the new ParameterValueSet
68      * @param hasReturnOutputParam if we have a ? = call syntax. Note that
69      * this is NOT the same thing as an output parameter -- return
70      * output parameters are special cases of output parameters.
71      */

72     GenericParameterValueSet(ClassInspector ci, int numParms, boolean hasReturnOutputParam)
73     {
74         this.ci = ci;
75         this.hasReturnOutputParam = hasReturnOutputParam;
76         parms = new GenericParameter[numParms];
77         for (int i = 0; i < numParms; i++)
78         {
79             /*
80             ** Last param is if this is a return output param. True if
81             ** we have an output param and we are on the 1st parameter.
82             */

83             parms[i] = new GenericParameter(this, (hasReturnOutputParam && i == 0));
84         }
85     }
86
87     /*
88     ** Construct a pvs by cloning a pvs.
89     */

90     private GenericParameterValueSet(int numParms, GenericParameterValueSet pvs)
91     {
92         this.hasReturnOutputParam = pvs.hasReturnOutputParam;
93         this.ci = pvs.ci;
94         parms = new GenericParameter[numParms];
95         for (int i = 0; i < numParms; i++)
96         {
97             parms[i] = pvs.getGenericParameter(i).getClone(this);
98         }
99     }
100
101     /*
102     ** ParameterValueSet interface methods
103     */

104     
105     /**
106      * Initialize the set by allocating a holder DataValueDescriptor object
107      * for each parameter.
108      */

109     public void initialize(DataTypeDescriptor[] types)
110     {
111         for (int i = 0; i < parms.length; i++)
112         {
113             DataTypeDescriptor dtd = types[i];
114             
115             parms[i].initialize(dtd.getNull(),
116                     dtd.getJDBCTypeId(), dtd.getTypeId().getCorrespondingJavaTypeName());
117         }
118     }
119
120     public void setParameterMode(int position, int mode) {
121         parms[position].parameterMode = (short) mode;
122     }
123
124     /**
125      * @see ParameterValueSet#clearParameters
126      */

127     public void clearParameters()
128     {
129         for (int i = 0; i < parms.length; i++)
130         {
131             parms[i].clear();
132         }
133     }
134
135     /**
136      * Returns the number of parameters in this set.
137      *
138      * @return The number of parameters in this set.
139      */

140     public int getParameterCount()
141     {
142         return parms.length;
143     }
144
145     /**
146      * Returns the parameter value at the given position.
147      *
148      * @return The parameter at the given position.
149      * @exception StandardException Thrown on error
150      */

151     public DataValueDescriptor getParameter( int position ) throws StandardException
152     {
153         try {
154             return parms[position].getValue();
155         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
156             checkPosition(position);
157             return null;
158         }
159     }
160
161
162
163     public DataValueDescriptor getParameterForSet(int position) throws StandardException {
164
165         try {
166
167             GenericParameter gp = parms[position];
168             if (gp.parameterMode == JDBC30Translation.PARAMETER_MODE_OUT)
169                 throw StandardException.newException(SQLState.LANG_RETURN_OUTPUT_PARAM_CANNOT_BE_SET);
170
171             gp.isSet = true;
172
173             return gp.getValue();
174         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
175             checkPosition(position);
176             return null;
177         }
178
179     }
180     
181     public DataValueDescriptor getParameterForGet(int position) throws StandardException {
182
183         try {
184
185             GenericParameter gp = parms[position];
186
187             switch (gp.parameterMode) {
188             case JDBC30Translation.PARAMETER_MODE_IN:
189             case JDBC30Translation.PARAMETER_MODE_UNKNOWN:
190                 throw StandardException.newException(SQLState.LANG_NOT_OUTPUT_PARAMETER, Integer.toString(position + 1));
191             }
192
193             return gp.getValue();
194         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
195             checkPosition(position);
196             return null;
197         }
198     }
199
200     public void setParameterAsObject(int position, Object JavaDoc value) throws StandardException {
201
202         UserDataValue dvd = (UserDataValue) getParameterForSet(position);
203
204         GenericParameter gp = parms[position];
205         if (value != null) {
206
207             {
208
209                 boolean throwError;
210                 ClassNotFoundException JavaDoc t = null;
211                 try {
212                     throwError = !ci.instanceOf(gp.declaredClassName, value);
213                 } catch (ClassNotFoundException JavaDoc cnfe) {
214                     t = cnfe;
215                     throwError = true;
216                 }
217
218                 if (throwError) {
219                     throw StandardException.newException(SQLState.LANG_DATA_TYPE_SET_MISMATCH, t,
220                         ClassInspector.readableClassName(value.getClass()), gp.declaredClassName);
221                 }
222             }
223
224         }
225
226         dvd.setValue(value);
227     }
228
229     /**
230      * @see ParameterValueSet#allAreSet
231      */

232     public boolean allAreSet()
233     {
234         for (int i = 0; i < parms.length; i++)
235         {
236             GenericParameter gp = parms[i];
237             if (!gp.isSet)
238             {
239                 switch (gp.parameterMode) {
240                 case JDBC30Translation.PARAMETER_MODE_OUT:
241                     break;
242                 case JDBC30Translation.PARAMETER_MODE_IN_OUT:
243                 case JDBC30Translation.PARAMETER_MODE_UNKNOWN:
244                 case JDBC30Translation.PARAMETER_MODE_IN:
245                     return false;
246                 }
247             }
248         }
249
250         return true;
251     }
252
253     /**
254      * @see ParameterValueSet#transferDataValues
255      */

256     public void transferDataValues(ParameterValueSet pvstarget) throws StandardException
257     {
258         // don't take application's values for return output parameters
259
int firstParam = pvstarget.hasReturnOutputParameter() ? 1 : 0;
260         for (int i = firstParam; i < parms.length;i++)
261         {
262
263             GenericParameter oldp = parms[i];
264
265             if (oldp.registerOutType != Types.NULL) {
266
267                 pvstarget.registerOutParameter(i, oldp.registerOutType, oldp.registerOutScale);
268
269             }
270
271             if (oldp.isSet)
272             {
273                 pvstarget.getParameterForSet(i).setValue(oldp.getValue());
274             }
275         }
276     }
277
278     GenericParameter getGenericParameter(int position)
279     {
280     return(parms[position]);
281   }
282
283     /* Class implementation */
284     public String JavaDoc toString()
285     {
286         /* This method needed for derby.language.logStatementText=true.
287          * Do not put under SanityManager.DEBUG.
288          */

289         StringBuffer JavaDoc strbuf = new StringBuffer JavaDoc();
290
291         for (int ctr = 0; ctr < parms.length; ctr++)
292         {
293             strbuf.append("begin parameter #" + (ctr + 1) + ": ");
294             strbuf.append(parms[ctr].toString());
295             strbuf.append(" :end parameter ");
296         }
297
298         return strbuf.toString();
299     }
300
301     /**
302      * Check the position number for a parameter and throw an exception if
303      * it is out of range.
304      *
305      * @param position The position number to check
306      *
307      * @exception StandardException Thrown if position number is
308      * out of range.
309      */

310     private void checkPosition(int position) throws StandardException
311     {
312         if (position < 0 || position >= parms.length)
313         {
314
315             if (parms.length == 0)
316                 throw StandardException.newException(SQLState.NO_INPUT_PARAMETERS);
317
318             throw StandardException.newException(SQLState.LANG_INVALID_PARAM_POSITION,
319                                                             String.valueOf(position+1),
320                                                             String.valueOf(parms.length));
321         }
322     }
323
324
325     public ParameterValueSet getClone()
326     {
327         return(new GenericParameterValueSet(parms.length, this));
328     }
329
330     //////////////////////////////////////////////////////////////////
331
//
332
// CALLABLE STATEMENT
333
//
334
//////////////////////////////////////////////////////////////////
335

336     /**
337      * Mark the parameter as an output parameter.
338      *
339      * @param parameterIndex The ordinal parameterIndex of a parameter to set
340      * to the given value.
341      * @param sqlType A type from java.sql.Types
342      * @param scale the scale to use. -1 means ignore scale
343      *
344      * @exception StandardException on error
345      */

346     public void registerOutParameter(int parameterIndex, int sqlType, int scale)
347         throws StandardException
348     {
349         checkPosition(parameterIndex);
350         parms[parameterIndex].setOutParameter(sqlType, scale);
351     }
352
353     /**
354      * Validate the parameters. This is done for situations where
355      * we cannot validate everything in the setXXX() calls. In
356      * particular, before we do an execute() on a CallableStatement,
357      * we need to go through the parameters and make sure that
358      * all parameters are set up properly. The motivator for this
359      * is that setXXX() can be called either before or after
360      * registerOutputParamter(), we cannot be sure we have the types
361      * correct until we get to execute().
362      *
363      * @exception StandardException if the parameters aren't valid
364      */

365     public void validate() throws StandardException
366     {
367         for (int i = 0; i < parms.length; i++)
368         {
369             parms[i].validate();
370         }
371     }
372
373
374     /**
375      * Return the parameter number (in jdbc lingo, i.e. 1 based)
376      * for the given parameter. Linear search.
377      *
378      * @return the parameter number, or 0 if not found
379      */

380     public int getParameterNumber(GenericParameter theParam)
381     {
382         for (int i = 0; i < parms.length; i++)
383         {
384             if (parms[i] == theParam)
385             {
386                 return i+1;
387             }
388         }
389         return 0;
390     }
391
392     /**
393         Check that there are not output parameters defined
394         by the parameter set. If there are unknown parameter
395         types they are forced to input types. i.e. Cloudscape static method
396         calls with parameters that are array.
397
398         @return true if a declared Java Procedure INOUT or OUT parameter is in the set, false otherwise.
399     */

400     public boolean checkNoDeclaredOutputParameters() {
401
402         boolean hasDeclaredOutputParameter = false;
403         for (int i=0; i<parms.length; i++) {
404
405             GenericParameter gp = parms[i];
406
407             switch (gp.parameterMode) {
408             case JDBC30Translation.PARAMETER_MODE_IN:
409                 break;
410             case JDBC30Translation.PARAMETER_MODE_IN_OUT:
411             case JDBC30Translation.PARAMETER_MODE_OUT:
412                 hasDeclaredOutputParameter = true;
413                 break;
414             case JDBC30Translation.PARAMETER_MODE_UNKNOWN:
415                 gp.parameterMode = JDBC30Translation.PARAMETER_MODE_IN;
416                 break;
417             }
418         }
419         return hasDeclaredOutputParameter;
420     }
421
422     /**
423         Return the mode of the parameter according to JDBC 3.0 ParameterMetaData
424      * @param parameterIndex the first parameter is 1, the second is 2, ...
425      *
426      */

427     public short getParameterMode(int parameterIndex)
428     {
429         short mode = parms[parameterIndex - 1].parameterMode;
430         //if (mode == (short) JDBC30Translation.PARAMETER_MODE_UNKNOWN)
431
// mode = (short) JDBC30Translation.PARAMETER_MODE_IN;
432
return mode;
433     }
434
435     /**
436      * Is there a return output parameter in this pvs. A return
437      * parameter is from a CALL statement of the following
438      * syntax: ? = CALL myMethod()
439      *
440      * @return true if it has a return parameter
441      *
442      */

443     public boolean hasReturnOutputParameter()
444     {
445         return hasReturnOutputParam;
446     }
447
448     /**
449      * Get the value of the return parameter in order to set it.
450      *
451      *
452      * @exception StandardException if a database-access error occurs.
453      */

454     public DataValueDescriptor getReturnValueForSet() throws StandardException
455     {
456         checkPosition(0);
457                 
458         if (SanityManager.DEBUG)
459         {
460             if (!hasReturnOutputParam)
461                 SanityManager.THROWASSERT("getReturnValueForSet called on non-return parameter");
462         }
463         
464         return parms[0].getValue();
465     }
466
467     /**
468      * Return the scale of the given parameter index in this pvs.
469      *
470      * @param parameterIndex the first parameter is 1, the second is 2, ...
471      *
472      * @return scale
473      */

474     public int getScale(int parameterIndex)
475     {
476         return parms[parameterIndex-1].getScale();
477     }
478
479     /**
480      * Return the precision of the given parameter index in this pvs.
481      *
482      * @param parameterIndex the first parameter is 1, the second is 2, ...
483      *
484      * @return precision
485      */

486     public int getPrecision(int parameterIndex)
487     {
488         return parms[parameterIndex-1].getPrecision();
489     }
490
491 }
492
Popular Tags