1 23 24 package org.objectweb.jorm.mapper.rdb.lib; 25 26 import org.objectweb.medor.api.MedorException; 27 import org.objectweb.medor.api.TupleStructure; 28 import org.objectweb.medor.expression.api.Operand; 29 import org.objectweb.medor.tuple.api.Tuple; 30 import org.objectweb.medor.tuple.api.TupleCollection; 31 import org.objectweb.medor.eval.prefetch.api.IntermediaryPrefetchBuffer; 32 import org.objectweb.medor.eval.prefetch.api.PrefetchBuffer; 33 import org.objectweb.medor.eval.prefetch.api.PrefetchBufferFactory; 34 import org.objectweb.medor.eval.prefetch.api.PrefetchBufferHolder; 35 import org.objectweb.medor.eval.prefetch.lib.IntermediaryPrefetchBufferImpl; 36 import org.objectweb.medor.eval.prefetch.lib.PrefetchBufferFactoryImpl; 37 import org.objectweb.jorm.mapper.rdb.adapter.api.RdbAdapter; 38 import org.objectweb.jorm.mapper.rdb.lib.PMapperRdb; 39 import org.objectweb.jorm.mapper.rdb.lib.PClassMappingDecoder; 40 import org.objectweb.jorm.api.PClassMapping; 41 import org.objectweb.jorm.api.PPrefetchTupleCollection; 42 import org.objectweb.util.monolog.api.BasicLevel; 43 import org.objectweb.util.monolog.api.Logger; 44 45 import java.math.BigDecimal ; 46 import java.math.BigInteger ; 47 import java.sql.ResultSet ; 48 import java.sql.PreparedStatement ; 49 import java.sql.SQLException ; 50 import java.util.Date ; 51 52 57 public class RdbTupleCollection 58 implements PPrefetchTupleCollection, Tuple, PrefetchBufferHolder { 59 60 63 private ResultSet resultSet; 64 65 68 private PreparedStatement preparedStatement; 69 70 73 private int pnameIndex; 74 75 78 private RdbAdapter rdbAdapter; 79 80 83 private PrefetchBuffer prefetchBuffer; 84 85 88 private PClassMapping pclassMapping; 89 90 94 private Object pnameGetter; 95 96 99 private static PrefetchBufferFactory pbf = new PrefetchBufferFactoryImpl(); 100 101 104 private int pos = 0; 105 106 private Logger logger; 107 108 public RdbTupleCollection(Object txctx, 109 ResultSet rs, 110 PreparedStatement ps, 111 int pi, 112 Logger l, 113 PClassMapping pcm, 114 boolean withSubType, 115 Object png) 116 throws MedorException, SQLException { 117 logger = l; 118 logger.log(BasicLevel.DEBUG, "TupleCollection creation"); 119 resultSet = rs; 120 preparedStatement = ps; 121 pnameIndex = pi; 122 rdbAdapter = ((PMapperRdb) pcm.getPMapper()).getRdbAdapter(); 123 pclassMapping = pcm; 124 pnameGetter = png; 125 boolean isPolymorphic = (pcm instanceof RdbPPolymorphicClass) && withSubType; 126 prefetchBuffer = pcm.getPMapper().getPrefetchCache().createPrefetchBuffer( 127 pbf, pcm, txctx, pi, !isPolymorphic); 128 prefetchBuffer.setTupleCollection(this); 129 if (isPolymorphic) { 131 IntermediaryPrefetchBuffer ipb = new IntermediaryPrefetchBufferImpl( 132 prefetchBuffer, 133 pcm.getIndexesTable(pcm)); 134 if (!pcm.getPMapper().getPrefetchCache().registerPrefetchBuffer( 135 ipb, pcm, txctx)) { 136 throw new MedorException("No prefetch buffer registered for the pcm " + pcm.getClassName() + "."); 137 } 138 try{ 139 PClassMapping[] subPCMs = pcm.getSubPCMs(); 141 if(subPCMs != null){ 142 for (int i = 0; i < subPCMs.length; i++) { 143 IntermediaryPrefetchBuffer intermediaryPb = new IntermediaryPrefetchBufferImpl( 147 prefetchBuffer, 148 subPCMs[i].getIndexesTable(pcm)); 149 if (!subPCMs[i].getPMapper().getPrefetchCache().registerPrefetchBuffer( 150 intermediaryPb, subPCMs[i], txctx)) { 151 throw new MedorException("No prefetch buffer registered for the pcm " + subPCMs[i].getClassName() + "."); 152 } 153 } 154 } 155 } 156 catch(Exception e){ 157 throw new MedorException("Error while trying to register the prefetchBuffer with the subclasses. ", e); 158 } 159 } 160 } 161 162 public PrefetchBuffer getPrefetchBuffer() { 163 return prefetchBuffer; 164 } 165 166 public int getPNameIndex() { 167 return pnameIndex; 168 } 169 170 public TupleStructure getMetaData() throws MedorException { 171 return null; 172 } 173 174 public boolean isLast() throws MedorException { 175 if (resultSet == null) { 176 throw new MedorException("Impossible to use a closed TupleCollection"); 177 } 178 logger.log(BasicLevel.DEBUG, ""); 179 try { 180 return resultSet.isLast(); 181 } catch (SQLException sqlex) { 182 throw new MedorException(sqlex); 183 } 184 } 185 186 public void close() throws MedorException { 187 if (resultSet != null) { 188 try { 189 resultSet.close(); 190 preparedStatement.close(); 191 } catch (SQLException e) { 192 throw new MedorException("Impossible to close the result set: ", e); 193 } finally { 194 resultSet = null; 195 preparedStatement = null; 196 } 197 } 198 } 199 200 204 public boolean next() throws MedorException { 205 if (resultSet == null) { 206 throw new MedorException("Impossible to use a closed TupleCollection"); 207 } 208 logger.log(BasicLevel.DEBUG, ""); 209 try { 210 if (resultSet.next()) { 211 pos++; 212 logger.log(BasicLevel.DEBUG, "resultset.next()=true"); 213 return true; 214 } else { 215 logger.log(BasicLevel.DEBUG, "resultset.next()=false"); 216 return false; 217 } 218 } catch (SQLException sqlex) { 219 throw new MedorException(sqlex); 220 } 221 } 222 223 226 public void first() throws MedorException { 227 if (resultSet == null) { 228 throw new MedorException("Impossible to use a closed TupleCollection"); 229 } 230 logger.log(BasicLevel.DEBUG, ""); 231 try { 232 if (resultSet.first()) { 233 pos = 1; 234 logger.log(BasicLevel.DEBUG, "resultset.previous()=true"); 235 } else 236 throw new MedorException("can't move the cursor to the first row"); 237 } catch (SQLException ex) { 238 throw new MedorException(ex); 239 } 240 } 241 242 245 public int getRow() throws MedorException { 246 return pos; 247 } 248 249 public Tuple getTuple() throws MedorException { 250 if (resultSet == null) { 251 throw new MedorException("Impossible to use a closed TupleCollection"); 252 } 253 logger.log(BasicLevel.DEBUG, ""); 254 return this; 255 } 256 257 public Tuple getTuple(int row) throws MedorException { 258 if (resultSet == null) { 259 throw new MedorException("Impossible to use a closed TupleCollection"); 260 } 261 row(row); 262 return this; 263 } 264 265 public boolean isEmpty() throws MedorException { 266 throw new MedorException("No need to support it here!!"); 267 } 268 269 public boolean row(int i) throws MedorException { 270 if (resultSet == null) { 271 throw new MedorException("Impossible to use a closed TupleCollection"); 272 } 273 try { 274 logger.log(BasicLevel.DEBUG, "resultSet.absolute(" + i + ")"); 275 if (pos == i) { 276 return true; 277 } 278 if (i == 1) { 279 first(); 280 return true; 281 } 282 if (pos == (i - 1)) { 283 return next(); 284 } 285 if (resultSet.absolute(i)) { 286 pos = i; 287 return true; 288 } else 289 return false; 290 } catch (SQLException sqlex) { 291 throw new MedorException(sqlex); 292 } 293 } 294 295 297 301 public int getSize() { 302 try { 303 return resultSet.getMetaData().getColumnCount() + 1; 304 } catch (SQLException e) { 305 return -1; 306 } 307 } 308 309 313 public Operand[] toOperandArray() { 314 return null; 315 } 316 317 322 public boolean getBoolean(int i) throws MedorException { 323 if (resultSet == null) { 324 throw new MedorException("Impossible to use a closed TupleCollection"); 325 } 326 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 327 try { 328 return rdbAdapter.getBoolean(resultSet, (i >= pnameIndex) ? i - 1 : i, false); 329 } catch (SQLException e) { 330 throw new MedorException(e); 331 } 332 } 333 334 338 public byte getByte(int i) throws MedorException { 339 if (resultSet == null) { 340 throw new MedorException("Impossible to use a closed TupleCollection"); 341 } 342 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 343 try { 344 return rdbAdapter.getByte(resultSet, (i >= pnameIndex) ? i - 1 : i, (byte) 0); 345 } catch (SQLException e) { 346 throw new MedorException(e); 347 } 348 } 349 350 354 public byte[] getByteArray(int i) throws MedorException { 355 if (resultSet == null) { 356 throw new MedorException("Impossible to use a closed TupleCollection"); 357 } 358 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 359 try { 360 return rdbAdapter.getByteArray(resultSet, (i >= pnameIndex) ? i - 1 : i, null); 361 } catch (SQLException e) { 362 throw new MedorException(e); 363 } 364 } 365 366 370 public char getChar(int i) throws MedorException { 371 if (resultSet == null) { 372 throw new MedorException("Impossible to use a closed TupleCollection"); 373 } 374 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 375 try { 376 return rdbAdapter.getChar(resultSet, (i >= pnameIndex) ? i - 1 : i, (char) 0); 377 } catch (SQLException e) { 378 throw new MedorException(e); 379 } 380 } 381 382 386 public char[] getCharArray(int i) throws MedorException { 387 if (resultSet == null) { 388 throw new MedorException("Impossible to use a closed TupleCollection"); 389 } 390 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 391 try { 392 return rdbAdapter.getCharArray(resultSet, (i >= pnameIndex) ? i - 1 : i, null); 393 } catch (SQLException e) { 394 throw new MedorException(e); 395 } 396 } 397 398 402 public Date getDate(int i) throws MedorException { 403 if (resultSet == null) { 404 throw new MedorException("Impossible to use a closed TupleCollection"); 405 } 406 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 407 try { 408 return rdbAdapter.getDate(resultSet, (i >= pnameIndex) ? i - 1 : i, null); 409 } catch (SQLException e) { 410 throw new MedorException(e); 411 } 412 } 413 414 418 public double getDouble(int i) throws MedorException { 419 if (resultSet == null) { 420 throw new MedorException("Impossible to use a closed TupleCollection"); 421 } 422 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 423 try { 424 return rdbAdapter.getDouble(resultSet, (i >= pnameIndex) ? i - 1 : i, ((double) 0.0)); 425 } catch (SQLException e) { 426 throw new MedorException(e); 427 } 428 } 429 430 434 public float getFloat(int i) throws MedorException { 435 if (resultSet == null) { 436 throw new MedorException("Impossible to use a closed TupleCollection"); 437 } 438 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 439 try { 440 return rdbAdapter.getFloat(resultSet, (i >= pnameIndex) ? i - 1 : i, ((float) 0.0)); 441 } catch (SQLException e) { 442 throw new MedorException(e); 443 } 444 } 445 446 450 public int getInt(int i) throws MedorException { 451 if (resultSet == null) { 452 throw new MedorException("Impossible to use a closed TupleCollection"); 453 } 454 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 455 try { 456 return rdbAdapter.getInt(resultSet, (i >= pnameIndex) ? i - 1 : i, -1); 457 } catch (SQLException e) { 458 throw new MedorException(e); 459 } 460 } 461 462 467 public Operand getLikeOperand(int i) throws MedorException { 468 return null; 469 } 470 471 475 public long getLong(int i) throws MedorException { 476 if (resultSet == null) { 477 throw new MedorException("Impossible to use a closed TupleCollection"); 478 } 479 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 480 try { 481 return rdbAdapter.getLong(resultSet, (i >= pnameIndex) ? i - 1 : i, ((long) -1)); 482 } catch (SQLException e) { 483 throw new MedorException(e); 484 } 485 } 486 487 492 public Object getObject(int i) throws MedorException { 493 if (resultSet == null) { 494 throw new MedorException("Impossible to use a closed TupleCollection"); 495 } 496 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 497 try { 498 if (i == pnameIndex) { 499 return ((PClassMappingDecoder) pclassMapping).decode(resultSet, pnameIndex, pnameGetter); 501 } else { 502 Object o = resultSet.getObject((i >= pnameIndex) ? i - 1 : i); 503 return (resultSet.wasNull() ? null : o); 504 } 505 } catch (SQLException sqlex) { 506 throw new MedorException(sqlex); 507 } catch (Exception e) { 508 throw new MedorException("Invalid field index " + i, e); 509 } 510 } 511 512 517 public short getShort(int i) throws MedorException { 518 if (resultSet == null) { 519 throw new MedorException("Impossible to use a closed TupleCollection"); 520 } 521 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 522 try { 523 return rdbAdapter.getShort(resultSet, (i >= pnameIndex) ? i - 1 : i, (short) -1); 524 } catch (SQLException e) { 525 throw new MedorException(e); 526 } 527 } 528 529 534 public BigDecimal getBigDecimal(int i) throws MedorException { 535 if (resultSet == null) { 536 throw new MedorException("Impossible to use a closed TupleCollection"); 537 } 538 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 539 try { 540 return rdbAdapter.getBigDecimal(resultSet, (i >= pnameIndex) ? i - 1 : i, null); 541 } catch (SQLException e) { 542 throw new MedorException(e); 543 } 544 } 545 546 551 public BigInteger getBigInteger(int i) throws MedorException { 552 if (resultSet == null) { 553 throw new MedorException("Impossible to use a closed TupleCollection"); 554 } 555 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 556 try { 557 BigDecimal bd = rdbAdapter.getBigDecimal(resultSet, (i >= pnameIndex) ? i - 1 : i, null); 558 return (bd == null) ? null : bd.toBigInteger(); 559 } catch (SQLException e) { 560 throw new MedorException(e); 561 } 562 } 563 564 569 public String getString(int i) throws MedorException { 570 if (resultSet == null) { 571 throw new MedorException("Impossible to use a closed TupleCollection"); 572 } 573 logger.log(BasicLevel.DEBUG, "numColumn=" + i); 574 try { 575 return rdbAdapter.getString(resultSet, (i >= pnameIndex) ? i - 1 : i, null); 576 } catch (SQLException e) { 577 throw new MedorException(e); 578 } 579 } 580 581 586 public TupleCollection getTupleCollection(int i) throws MedorException { 587 return this; 588 } 589 590 public boolean isDefined(int i) { 591 try { 592 return !resultSet.wasNull(); 593 } catch (SQLException e) { 594 return false; 595 } 596 } 597 598 600 public void invalidatePrefetchBuffer() throws MedorException { 601 logger.log(BasicLevel.DEBUG, "Invalidating PrefetchBuffer " + prefetchBuffer + " for " + this); 602 prefetchBuffer = null; 603 if (prefetchBuffer != null) { 604 this.close(); 605 prefetchBuffer = null; 606 } else { 607 logger.log(BasicLevel.DEBUG, "The tupleCollection was closed earlier: closing it for real"); 608 } 609 } 610 } 611 | Popular Tags |