KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > datasource > rdb > lib > JDBCTupleCollection


1 /**
2  * Copyright (C) 2001-2003 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package org.objectweb.medor.datasource.rdb.lib;
19
20 import org.objectweb.medor.tuple.api.TupleCollection;
21 import org.objectweb.medor.tuple.api.Tuple;
22 import org.objectweb.medor.tuple.lib.MemoryTuple;
23 import org.objectweb.medor.api.MedorException;
24 import org.objectweb.medor.api.TupleStructure;
25 import org.objectweb.medor.type.lib.QType;
26 import org.objectweb.medor.expression.api.VariableOperand;
27 import org.objectweb.medor.expression.api.ExpressionException;
28 import org.objectweb.medor.expression.lib.BasicVariableOperand;
29 import org.objectweb.jorm.mapper.rdb.adapter.api.RdbAdapter;
30 import org.objectweb.jorm.type.api.PType;
31 import org.objectweb.util.monolog.api.Logger;
32 import org.objectweb.util.monolog.api.BasicLevel;
33
34 import java.sql.ResultSet JavaDoc;
35 import java.sql.PreparedStatement JavaDoc;
36 import java.sql.SQLException JavaDoc;
37
38 /**
39  * This class encapsulates a resultset as a TupleCollection.
40  *
41  * @author S.Chassande-Barrioz
42  */

43 public class JDBCTupleCollection implements TupleCollection {
44
45     private ResultSet JavaDoc resultSet;
46     private TupleStructure tupleStructure;
47     private VariableOperand[] operandBuffer;
48     private Tuple buffer;
49     private RdbAdapter adapter;
50     private PreparedStatement JavaDoc preparedStatement;
51     private boolean debug;
52     private Logger log;
53     private int index;
54     private boolean isLast = false;
55
56     /**
57      * @param tupleStructure is the TupleStructure describing the struture
58      * of the TupleCollection.
59      * @param rs is the encapsulated ResultSet. The resultset is already
60      * positioned on the first element.
61      * @param ps is the PreparedStatement which must be closed in same time than
62      * this tuple collection and the ResultSet.
63      * @param adapter is the RdbAdapter to use
64      * @param logger
65      */

66     public JDBCTupleCollection(TupleStructure tupleStructure,
67                                ResultSet JavaDoc rs,
68                                PreparedStatement JavaDoc ps,
69                                RdbAdapter adapter,
70                                Logger logger)
71             throws MedorException, ExpressionException, SQLException JavaDoc {
72         log = logger;
73         debug = log.isLoggable(BasicLevel.DEBUG);
74         if (debug) log.log(BasicLevel.DEBUG, "JDBCTupleCollection creation");
75         this.tupleStructure = tupleStructure;
76         resultSet = rs;
77         int size = tupleStructure.getSize();
78         // create and init the buffer
79
operandBuffer = new VariableOperand[size];
80         for (int cpt = 0; cpt < size; cpt++) {
81             operandBuffer[cpt] = new BasicVariableOperand(
82                     tupleStructure.getField(cpt + 1).getType());
83         }
84         buffer = new MemoryTuple(operandBuffer);
85         this.adapter = adapter;
86         preparedStatement = ps;
87         index = 0;
88         isLast = false;
89         next();
90     }
91
92     public TupleStructure getMetaData() throws MedorException {
93         return tupleStructure;
94     }
95
96     /**
97      * Checks whether the current row is the last row.
98      * <p>This method relies on the resultSet.next() method, and not on the
99      * resultSet.isLast() method, since isLast is not supported by all JDBC
100      * drivers. Method next() of this class first checks whether
101      * resultSet.next() has already been called by isLast before calling it.</p>
102      * @return true if it was the last row, false otherwise
103      * @throws MedorException if there is a SQL exception
104      */

105     public boolean isLast() throws MedorException {
106         if (resultSet == null) {
107             throw new MedorException("Impossible to use a closed TupleCollection");
108         }
109         if (debug) log.log(BasicLevel.DEBUG, "");
110         return isLast;
111     }
112
113     public void close() throws MedorException {
114         if (resultSet != null) {
115             synchronized (this) {
116                 if (resultSet != null) {
117                     try {
118                         resultSet.close();
119                         preparedStatement.close();
120                     }
121                     catch (SQLException JavaDoc e) {
122                         throw new MedorException("Impossible to close the result set: ", e);
123                     }
124                     finally {
125                         resultSet = null;
126                         preparedStatement = null;
127                         tupleStructure = null;
128                         buffer = null;
129                         adapter = null;
130                         operandBuffer = null;
131                     }
132                 }
133             }
134         }
135     }
136
137     /**
138      * Moves the cursor down one row from its current position to the next
139      * row.
140      * <p>Note that nothing is done in the case resultSet.next() was already
141      * called when calling isLast().
142      * @return true if there was a next row, false if there is no next row.
143      * @throws MedorException if there is a SQL Exception.
144      */

145     public boolean next() throws MedorException {
146         if (resultSet == null) {
147             throw new MedorException("Impossible to use a closed TupleCollection");
148         }
149         if (isLast) {
150             if (debug) log.log(BasicLevel.DEBUG, "No more result");
151             return false;
152         }
153         try {
154             loadTuple();
155             index ++;
156             //compute the isLast value by calling the resultSet
157
isLast = !resultSet.next();
158             if (debug) {
159                 log.log(BasicLevel.DEBUG, "Current tuple load from the resultset, index="
160                     + index + ", isLast=" + isLast);
161             }
162         } catch (SQLException JavaDoc sqlex) {
163             throw new MedorException(sqlex);
164         } catch (ExpressionException sqlex) {
165             throw new MedorException(sqlex);
166         }
167         return true;
168     }
169
170     /**
171      * Moves the cursor to the first Tuple of this TupleCollection
172      */

173     public void first() throws MedorException {
174         if (resultSet == null) {
175             throw new MedorException("Impossible to use a closed TupleCollection");
176         }
177         if (debug) log.log(BasicLevel.DEBUG, "");
178         if (index == 1) {
179             return;
180         }
181         try {
182             if (resultSet.first()) {
183                 index = 0;
184                 isLast = false;
185                 next();
186                 if (debug) log.log(BasicLevel.DEBUG, "resultset.previous()=true");
187             } else
188                 throw new MedorException("can't move the cursor to the first row");
189         } catch (SQLException JavaDoc ex) {
190             throw new MedorException(ex);
191         }
192     }
193
194     /**
195      * Retrieves the current row Number of this TupleCollection
196      */

197     public int getRow() throws MedorException {
198         if (resultSet == null) {
199             throw new MedorException("Impossible to use a closed TupleCollection");
200         }
201         if (debug) log.log(BasicLevel.DEBUG, "");
202         return index;
203     }
204
205     public Tuple getTuple() throws MedorException {
206         if (resultSet == null) {
207             throw new MedorException("Impossible to use a closed TupleCollection");
208         }
209         if (debug) log.log(BasicLevel.DEBUG, "");
210         return buffer;
211     }
212
213     private void loadTuple()
214             throws ExpressionException, MedorException, SQLException JavaDoc {
215         PType ptype = null;
216         int size = tupleStructure.getSize();
217         StringBuffer JavaDoc sb;
218         if (debug) {
219             sb = new StringBuffer JavaDoc();
220         }
221         for (int cpt = 1; cpt <= size; cpt++) {
222             ptype = tupleStructure.getField(cpt).getType();
223             switch (ptype.getTypeCode()) {
224             case QType.TYPECODE_INT:
225                 operandBuffer[cpt - 1].setValue(adapter.getInt(resultSet, cpt, -1));
226                 operandBuffer[cpt - 1].setIsDefined(!resultSet.wasNull());
227                 break;
228             case QType.TYPECODE_SHORT:
229                 operandBuffer[cpt - 1].setValue(adapter.getShort(resultSet, cpt, (short) -1));
230                 operandBuffer[cpt - 1].setIsDefined(!resultSet.wasNull());
231                 break;
232             case QType.TYPECODE_BYTE:
233                 operandBuffer[cpt - 1].setValue(adapter.getByte(resultSet, cpt, (byte) -1));
234                 operandBuffer[cpt - 1].setIsDefined(!resultSet.wasNull());
235                 break;
236             case QType.TYPECODE_LONG:
237                 operandBuffer[cpt - 1].setValue(adapter.getLong(resultSet, cpt, -1));
238                 operandBuffer[cpt - 1].setIsDefined(!resultSet.wasNull());
239                 break;
240             case QType.TYPECODE_DOUBLE:
241                 operandBuffer[cpt - 1].setValue(adapter.getDouble(resultSet, cpt, -1));
242                 operandBuffer[cpt - 1].setIsDefined(!resultSet.wasNull());
243                 break;
244             case QType.TYPECODE_BOOLEAN:
245                 operandBuffer[cpt - 1].setValue(adapter.getBoolean(resultSet, cpt, false));
246                 operandBuffer[cpt - 1].setIsDefined(!resultSet.wasNull());
247                 break;
248             case QType.TYPECODE_FLOAT:
249                 operandBuffer[cpt - 1].setValue(adapter.getFloat(resultSet, cpt, 0));
250                 operandBuffer[cpt - 1].setIsDefined(!resultSet.wasNull());
251                 break;
252             case QType.TYPECODE_STRING:
253                 operandBuffer[cpt - 1].setValue(adapter.getString(resultSet, cpt, null));
254                 break;
255             case QType.TYPECODE_OBJBOOLEAN:
256                 operandBuffer[cpt - 1].setValue(adapter.getOboolean(resultSet, cpt, null));
257                 break;
258             case QType.TYPECODE_OBJCHAR:
259                 operandBuffer[cpt - 1].setValue(adapter.getOchar(resultSet, cpt, null));
260                 break;
261             case QType.TYPECODE_OBJBYTE:
262                 operandBuffer[cpt - 1].setValue(adapter.getObyte(resultSet, cpt, null));
263                 break;
264             case QType.TYPECODE_OBJSHORT:
265                 operandBuffer[cpt - 1].setValue(adapter.getOshort(resultSet, cpt, null));
266                 break;
267             case QType.TYPECODE_OBJINT:
268                 operandBuffer[cpt - 1].setValue(adapter.getOint(resultSet, cpt, null));
269                 break;
270             case QType.TYPECODE_OBJLONG:
271                 operandBuffer[cpt - 1].setValue(adapter.getOlong(resultSet, cpt, null));
272                 break;
273             case QType.TYPECODE_OBJFLOAT:
274                 operandBuffer[cpt - 1].setValue(adapter.getOfloat(resultSet, cpt, null));
275                 break;
276             case QType.TYPECODE_OBJDOUBLE:
277                 operandBuffer[cpt - 1].setValue(adapter.getOdouble(resultSet, cpt, null));
278                 break;
279             case QType.TYPECODE_DATE:
280                 operandBuffer[cpt - 1].setValue(adapter.getDate(resultSet, cpt, null));
281                 break;
282             case QType.TYPECODE_CHAR:
283                 operandBuffer[cpt - 1].setValue(adapter.getChar(resultSet, cpt, (char) 0));
284                 operandBuffer[cpt - 1].setIsDefined(!resultSet.wasNull());
285                 break;
286             case QType.TYPECODE_BYTEARRAY:
287                 operandBuffer[cpt - 1].setValue(adapter.getByteArray(resultSet, cpt, null));
288                 operandBuffer[cpt - 1].setIsDefined(!resultSet.wasNull());
289                 break;
290             case QType.TYPECODE_CHARARRAY:
291                 operandBuffer[cpt - 1].setValue(adapter.getCharArray(resultSet, cpt, null));
292                 operandBuffer[cpt - 1].setIsDefined(!resultSet.wasNull());
293                 break;
294             case QType.TYPECODE_BIGDECIMAL:
295                 operandBuffer[cpt - 1].setValue(adapter.getBigDecimal(resultSet, cpt, null));
296                 break;
297             case QType.TYPECODE_BIGINTEGER:
298                 operandBuffer[cpt - 1].setValue(adapter.getBigInteger(resultSet, cpt, null));
299                 break;
300             case PType.TYPECODE_SERIALIZED:
301                 try {
302                     operandBuffer[cpt - 1].setValue(adapter.getSerialized(resultSet, cpt, null));
303                 }
304                 catch (Exception JavaDoc e) {
305                     throw new MedorException("Impossible to fetch a serialized field a the index " + cpt, e);
306                 }
307                 break;
308             }
309         }
310         if (debug) {
311             sb = new StringBuffer JavaDoc("[");
312             String JavaDoc sep = "";
313             for (int cpt = 0; cpt < size; cpt++) {
314                 sb.append(sep);
315                 sb.append(operandBuffer[cpt]);
316                 sep = ",";
317             }
318             sb.append(']');
319             log.log(BasicLevel.DEBUG, "Tuple loaded: " + sb.toString());
320         }
321
322     }
323
324     public Tuple getTuple(int row) throws MedorException {
325         if (row(row)) {
326             return getTuple();
327         } else {
328             throw new MedorException("Can't move to the row: " + row);
329         }
330     }
331
332     public boolean isEmpty() throws MedorException {
333         if (resultSet == null) {
334             throw new MedorException("Impossible to use a closed TupleCollection");
335         }
336         if (debug) log.log(BasicLevel.DEBUG, "return " + (buffer == null));
337         return (buffer == null);
338     }
339
340     public boolean row(int i) throws MedorException {
341         if (resultSet == null) {
342             throw new MedorException("Impossible to use a closed TupleCollection");
343         }
344         if (index == i) {
345             return true;
346         }
347         try {
348             if (debug) log.log(BasicLevel.DEBUG, "resultSet.absolute(" + i + ")");
349             if (resultSet.absolute(i)) {
350                 index = i-1;
351                 isLast = false;
352                 next();
353                 return true;
354             } else
355                 return false;
356         } catch (SQLException JavaDoc sqlex) {
357             throw new MedorException(sqlex);
358         }
359     }
360 }
361
362
363
Popular Tags