1 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 ; 35 import java.sql.PreparedStatement ; 36 import java.sql.SQLException ; 37 38 43 public class JDBCTupleCollection implements TupleCollection { 44 45 private ResultSet resultSet; 46 private TupleStructure tupleStructure; 47 private VariableOperand[] operandBuffer; 48 private Tuple buffer; 49 private RdbAdapter adapter; 50 private PreparedStatement preparedStatement; 51 private boolean debug; 52 private Logger log; 53 private int index; 54 private boolean isLast = false; 55 56 66 public JDBCTupleCollection(TupleStructure tupleStructure, 67 ResultSet rs, 68 PreparedStatement ps, 69 RdbAdapter adapter, 70 Logger logger) 71 throws MedorException, ExpressionException, SQLException { 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 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 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 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 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 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 sqlex) { 163 throw new MedorException(sqlex); 164 } catch (ExpressionException sqlex) { 165 throw new MedorException(sqlex); 166 } 167 return true; 168 } 169 170 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 ex) { 190 throw new MedorException(ex); 191 } 192 } 193 194 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 { 215 PType ptype = null; 216 int size = tupleStructure.getSize(); 217 StringBuffer sb; 218 if (debug) { 219 sb = new StringBuffer (); 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 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 ("["); 312 String 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 sqlex) { 357 throw new MedorException(sqlex); 358 } 359 } 360 } 361 362 363 | Popular Tags |