1 29 30 package com.caucho.db.sql; 31 32 import com.caucho.db.jdbc.GeneratedKeysResultSet; 33 import com.caucho.db.store.Block; 34 import com.caucho.db.store.Transaction; 35 import com.caucho.db.table.TableIterator; 36 import com.caucho.log.Log; 37 import com.caucho.util.FreeList; 38 import com.caucho.util.L10N; 39 40 import java.io.IOException ; 41 import java.sql.SQLException ; 42 import java.util.HashMap ; 43 import java.util.Iterator ; 44 import java.util.logging.Level ; 45 import java.util.logging.Logger ; 46 47 50 public class QueryContext { 51 private static final Logger log = Log.open(QueryContext.class); 52 private static final L10N L = new L10N(QueryContext.class); 53 54 private static final long LOCK_TIMEOUT = 120000; 55 56 private static final FreeList<QueryContext> _freeList 57 = new FreeList<QueryContext>(64); 58 59 private Transaction _xa; 60 private TableIterator []_tableIterators; 61 private boolean _isWrite; 62 63 private Data []_parameters = new Data[8]; 64 65 private GroupItem _tempGroupItem; 66 private GroupItem _groupItem; 67 68 private boolean _isReturnGeneratedKeys; 69 private SelectResult _result; 70 private GeneratedKeysResultSet _generatedKeys; 71 private int _rowUpdateCount; 72 73 private Block []_blockLocks; 74 private boolean _isLocked; 75 76 private HashMap <GroupItem,GroupItem> _groupMap; 77 78 private byte []_buffer = new byte[256]; 79 80 private QueryContext() 81 { 82 _tempGroupItem = GroupItem.allocate(new boolean[8]); 83 } 84 85 88 public static QueryContext allocate() 89 { 90 QueryContext queryContext = _freeList.allocate(); 91 92 if (queryContext == null) 93 queryContext = new QueryContext(); 94 95 queryContext.clearParameters(); 96 97 return queryContext; 98 } 99 100 public void clearParameters() 101 { 102 for (int i = _parameters.length - 1; i >= 0; i--) { 103 if (_parameters[i] == null) 104 _parameters[i] = new Data(); 105 106 _parameters[i].clear(); 107 } 108 } 109 110 113 public void init(Transaction xa, 114 TableIterator []tableIterators, 115 boolean isReadOnly) 116 { 117 _xa = xa; 118 _isWrite = ! isReadOnly; 119 _tableIterators = tableIterators; 120 _blockLocks = new Block[_tableIterators.length]; 121 _isLocked = false; 122 123 _rowUpdateCount = 0; 124 _groupItem = _tempGroupItem; 125 _groupItem.init(0, null); 126 } 127 128 131 public void initGroup(int size, boolean []isGroupByFields) 132 { 133 _groupItem = _tempGroupItem; 134 135 _groupItem.init(size, isGroupByFields); 136 137 if (_groupMap == null) 138 _groupMap = new HashMap <GroupItem,GroupItem>(); 139 } 140 141 144 public void selectGroup() 145 { 146 GroupItem item = _groupMap.get(_groupItem); 147 148 if (item == null) { 149 item = _groupItem.allocateCopy(); 150 151 _groupMap.put(item, item); 152 } 153 154 _groupItem = item; 155 } 156 157 160 Iterator<GroupItem> groupResults() 161 { 162 if (_groupMap == null) 163 return com.caucho.util.NullIterator.create(); 164 165 Iterator<GroupItem> results = _groupMap.values().iterator(); 166 _groupMap = null; 167 168 return results; 169 } 170 171 174 void setGroupItem(GroupItem item) 175 { 176 _groupItem = item; 177 } 178 179 180 183 public TableIterator []getTableIterators() 184 { 185 return _tableIterators; 186 } 187 188 191 public void setTransaction(Transaction xa) 192 { 193 _xa = xa; 194 } 195 196 199 public Transaction getTransaction() 200 { 201 return _xa; 202 } 203 204 207 public byte []getBuffer() 208 { 209 return _buffer; 210 } 211 212 215 public int getRowUpdateCount() 216 { 217 return _rowUpdateCount; 218 } 219 220 223 public void setRowUpdateCount(int count) 224 { 225 _rowUpdateCount = count; 226 } 227 228 231 public boolean isReturnGeneratedKeys() 232 { 233 return _isReturnGeneratedKeys; 234 } 235 236 239 public void setReturnGeneratedKeys(boolean isReturnGeneratedKeys) 240 { 241 _isReturnGeneratedKeys = isReturnGeneratedKeys; 242 243 if (_isReturnGeneratedKeys && _generatedKeys != null) 244 _generatedKeys.init(); 245 } 246 247 250 public boolean isGroupNull(int index) 251 { 252 return _groupItem.isNull(index); 253 } 254 255 258 public void setGroupString(int index, String value) 259 { 260 _groupItem.setString(index, value); 261 } 262 263 266 public String getGroupString(int index) 267 { 268 return _groupItem.getString(index); 269 } 270 271 274 public void setGroupLong(int index, long value) 275 { 276 _groupItem.setLong(index, value); 277 } 278 279 282 public long getGroupLong(int index) 283 { 284 return _groupItem.getLong(index); 285 } 286 287 290 public void setGroupDouble(int index, double value) 291 { 292 _groupItem.setDouble(index, value); 293 } 294 295 298 public double getGroupDouble(int index) 299 { 300 return _groupItem.getDouble(index); 301 } 302 303 306 public Data getGroupData(int index) 307 { 308 return _groupItem.getData(index); 309 } 310 311 314 public void setNull(int index) 315 { 316 _parameters[index].setString(null); 317 } 318 319 322 public boolean isNull(int index) 323 { 324 return _parameters[index].isNull(); 325 } 326 327 330 public void setLong(int index, long value) 331 { 332 _parameters[index].setLong(value); 333 } 334 335 338 public int getBoolean(int index) 339 { 340 return _parameters[index].getBoolean(); 341 } 342 343 346 public void setBoolean(int index, boolean value) 347 { 348 _parameters[index].setBoolean(value); 349 } 350 351 354 public long getLong(int index) 355 { 356 return _parameters[index].getLong(); 357 } 358 359 362 public long getDate(int index) 363 { 364 return _parameters[index].getDate(); 365 } 366 367 370 public void setDouble(int index, double value) 371 { 372 _parameters[index].setDouble(value); 373 } 374 375 378 public double getDouble(int index) 379 { 380 return _parameters[index].getDouble(); 381 } 382 383 386 public void setString(int index, String value) 387 { 388 _parameters[index].setString(value); 389 } 390 391 394 public String getString(int index) 395 { 396 return _parameters[index].getString(); 397 } 398 399 402 public void setResult(SelectResult result) 403 { 404 _result = result; 405 } 406 407 410 public SelectResult getResult() 411 { 412 return _result; 413 } 414 415 418 public GeneratedKeysResultSet getGeneratedKeysResultSet() 419 { 420 if (! _isReturnGeneratedKeys) 421 return null; 422 423 if (_generatedKeys == null) 424 _generatedKeys = new GeneratedKeysResultSet(); 425 426 return _generatedKeys; 427 } 428 429 435 public void lock() 436 throws SQLException 437 { 438 if (_isLocked) 439 throw new IllegalStateException (L.l("blocks are already locked")); 440 _isLocked = true; 441 442 int len = _blockLocks.length; 443 444 for (int i = 0; i < len; i++) { 445 Block bestBlock = null; 446 long bestId = Long.MAX_VALUE; 447 448 loop: 449 for (int j = 0; j < len; j++) { 450 TableIterator iter = _tableIterators[j]; 451 452 if (iter == null) 453 continue; 454 455 Block block = iter.getBlock(); 456 457 if (block == null) 458 continue; 459 460 long id = block.getBlockId(); 461 if (bestId <= id) 462 continue; 463 464 for (int k = 0; k < i; k++) { 465 if (_blockLocks[k] == block) 466 continue loop; 467 } 468 469 bestId = id; 470 bestBlock = block; 471 } 472 473 _blockLocks[i] = bestBlock; 474 475 if (bestBlock == null) { 476 } 477 else if (_isWrite) 478 _xa.lockWrite(bestBlock.getLock()); 479 else 480 _xa.lockRead(bestBlock.getLock()); 481 } 482 } 483 484 489 public void unlock() 490 throws SQLException 491 { 492 if (! _isLocked) 493 return; 494 495 _isLocked = false; 496 497 try { 498 _xa.writeData(); 499 } finally { 500 int len = _blockLocks.length; 501 502 for (int i = len - 1; i >= 0; i--) { 503 Block block = _blockLocks[i]; 504 _blockLocks[i] = null; 505 506 if (block == null) { 507 } 508 else if (_isWrite) { 509 _xa.unlockReadAndWrite(block.getLock()); 510 511 try { 512 block.commit(); 513 } catch (IOException e) { 514 log.log(Level.FINE, e.toString(), e); 515 } 516 } 517 else 518 _xa.unlockRead(block.getLock()); 519 } 520 } 521 } 522 523 526 public static void free(QueryContext queryContext) 527 { 528 queryContext._groupMap = null; 529 530 _freeList.free(queryContext); 531 } 532 } 533 | Popular Tags |