1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 import org.apache.derby.iapi.error.PublicAPI; 26 import org.apache.derby.iapi.db.TriggerExecutionContext; 27 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 28 import org.apache.derby.iapi.sql.ResultSet; 29 import org.apache.derby.iapi.sql.execute.CursorResultSet; 30 import org.apache.derby.iapi.sql.execute.ExecRow; 31 import org.apache.derby.iapi.types.DataValueDescriptor; 32 import org.apache.derby.iapi.sql.execute.ExecutionStmtValidator; 33 import org.apache.derby.iapi.sql.execute.ConstantAction; 34 import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor; 35 import org.apache.derby.iapi.error.StandardException; 36 import org.apache.derby.iapi.services.i18n.MessageService; 37 import org.apache.derby.iapi.reference.SQLState; 38 import org.apache.derby.iapi.jdbc.ConnectionContext; 39 import org.apache.derby.catalog.UUID; 40 import java.util.Enumeration ; 41 import java.util.Vector ; 42 import java.util.Hashtable ; 43 import java.sql.Connection ; 44 import java.sql.SQLException ; 45 import java.sql.Statement ; 46 import org.apache.derby.iapi.error.ExceptionSeverity; 47 61 public class InternalTriggerExecutionContext implements TriggerExecutionContext, ExecutionStmtValidator 62 { 63 66 protected int[] changedColIds; 67 protected String [] changedColNames; 68 protected int dmlType; 69 protected String statementText; 70 protected ConnectionContext cc; 71 protected UUID targetTableId; 72 protected String targetTableName; 73 protected LanguageConnectionContext lcc; 74 75 78 protected CursorResultSet beforeResultSet; 79 protected CursorResultSet afterResultSet; 80 81 85 protected ExecRow afterRow; 86 87 protected boolean cleanupCalled; 88 protected TriggerEvent event; 89 protected TriggerDescriptor triggerd; 90 91 98 private Vector resultSetVector; 99 100 108 private Vector aiCounters; 109 110 114 private Hashtable aiHT; 115 116 141 public InternalTriggerExecutionContext 142 ( 143 LanguageConnectionContext lcc, 144 ConnectionContext cc, 145 String statementText, 146 int dmlType, 147 int[] changedColIds, 148 String [] changedColNames, 149 UUID targetTableId, 150 String targetTableName, 151 Vector aiCounters 152 ) throws StandardException 153 { 154 this.dmlType = dmlType; 155 this.changedColIds = changedColIds; 156 this.changedColNames = changedColNames; 157 this.statementText = statementText; 158 this.cc = cc; 159 this.lcc = lcc; 160 this.targetTableId = targetTableId; 161 this.targetTableName = targetTableName; 162 this.resultSetVector = new Vector (); 163 this.aiCounters = aiCounters; 164 165 if (SanityManager.DEBUG) 166 { 167 if ((changedColIds == null) != (changedColNames == null)) 168 { 169 SanityManager.THROWASSERT("bad changed cols, "+ 170 "(changedColsIds == null) = "+(changedColIds == null)+ 171 " (changedColsNames == null) = "+(changedColNames == null)); 172 } 173 if (changedColIds != null) 174 { 175 SanityManager.ASSERT(changedColIds.length == changedColNames.length, 176 "different number of changed col ids vs names"); 177 } 178 } 179 180 lcc.pushTriggerExecutionContext(this); 181 } 182 183 void setBeforeResultSet(CursorResultSet rs) 184 { 185 beforeResultSet = rs; 186 } 187 188 void setAfterResultSet(CursorResultSet rs) 189 throws StandardException 190 { 191 afterResultSet = rs; 192 193 if (aiCounters != null) 194 { 195 if (triggerd.isRowTrigger()) 196 { 197 rs.open(); 199 afterRow = rs.getNextRow(); 200 rs.close(); 201 } 202 else 203 { 204 if (!triggerd.isBeforeTrigger()) 206 resetAICounters(false); 207 } 208 } 209 } 210 211 void setCurrentTriggerEvent(TriggerEvent event) 212 { 213 this.event = event; 214 } 215 216 void clearCurrentTriggerEvent() 217 { 218 event = null; 219 } 220 221 void setTrigger(TriggerDescriptor triggerd) 222 { 223 this.triggerd = triggerd; 224 } 225 226 void clearTrigger() throws StandardException 227 { 228 event = null; 229 triggerd = null; 230 if (afterResultSet != null) 231 { 232 afterResultSet.close(); 233 afterResultSet = null; 234 } 235 if (beforeResultSet != null) 236 { 237 beforeResultSet.close(); 238 beforeResultSet = null; 239 } 240 } 241 242 254 protected void cleanup() 255 throws StandardException 256 { 257 lcc.popTriggerExecutionContext(this); 258 259 263 for (Enumeration e = resultSetVector.elements(); 264 e.hasMoreElements(); ) 265 { 266 java.sql.ResultSet rs = (java.sql.ResultSet )e.nextElement(); 267 try 268 { 269 rs.close(); 270 } catch (SQLException se) {} 271 } 272 resultSetVector = null; 273 274 280 if (afterResultSet != null) 281 { 282 afterResultSet.close(); 283 afterResultSet = null; 284 } 285 if (beforeResultSet != null) 286 { 287 beforeResultSet.close(); 288 beforeResultSet = null; 289 } 290 291 lcc = null; 292 cleanupCalled = true; 293 } 294 295 299 private void ensureProperContext() throws SQLException 300 { 301 if (cleanupCalled) 302 { 303 throw new SQLException ( 304 MessageService.getTextMessage( 305 SQLState.LANG_STATEMENT_CLOSED_NO_REASON), 306 "XCL31", 307 ExceptionSeverity.STATEMENT_SEVERITY 308 ); 309 } 310 } 311 312 329 public void validateStatement(ConstantAction constantAction) throws StandardException 330 { 331 332 if (constantAction instanceof DDLConstantAction) { 337 throw StandardException.newException(SQLState.LANG_NO_DDL_IN_TRIGGER, triggerd.getName(), constantAction.toString()); 338 } 339 340 346 } 347 348 354 360 public String getTargetTableName() 361 { 362 return targetTableName; 363 } 364 365 371 public UUID getTargetTableId() 372 { 373 return targetTableId; 374 } 375 376 382 public int getEventType() 383 { 384 return dmlType; 385 } 386 387 393 public String getEventStatementText() 394 { 395 return statementText; 396 } 397 398 406 public String [] getModifiedColumns() 407 { 408 return changedColNames; 409 } 410 411 420 public boolean wasColumnModified(String columnName) 421 { 422 if (changedColNames == null) 423 { 424 return true; 425 } 426 427 for (int i = 0; i < changedColNames.length; i++) 428 { 429 if (changedColNames[i].equals(columnName)) 430 { 431 return true; 432 } 433 } 434 return false; 435 } 436 437 446 public boolean wasColumnModified(int columnNumber) 447 { 448 if (changedColIds == null) 449 { 450 return true; 451 } 452 453 for (int i = 0; i < changedColNames.length; i++) 454 { 455 if (changedColIds[i] == columnNumber) 456 { 457 return true; 458 } 459 } 460 return false; 461 } 462 463 477 public java.sql.ResultSet getOldRowSet() throws SQLException 478 { 479 ensureProperContext(); 480 if (beforeResultSet == null) 481 { 482 return null; 483 } 484 485 try 486 { 487 CursorResultSet brs = beforeResultSet; 488 492 if (brs instanceof TemporaryRowHolderResultSet) 493 brs = (CursorResultSet) ((TemporaryRowHolderResultSet) brs).clone(); 494 else if (brs instanceof TableScanResultSet) 495 brs = (CursorResultSet) ((TableScanResultSet) brs).clone(); 496 brs.open(); 497 java.sql.ResultSet rs = cc.getResultSet(brs); 498 resultSetVector.addElement(rs); 499 return rs; 500 } catch (StandardException se) 501 { 502 throw PublicAPI.wrapStandardException(se); 503 } 504 } 505 506 520 public java.sql.ResultSet getNewRowSet() throws SQLException 521 { 522 ensureProperContext(); 523 524 if (afterResultSet == null) 525 { 526 return null; 527 } 528 try 529 { 530 534 CursorResultSet ars = afterResultSet; 535 if (ars instanceof TemporaryRowHolderResultSet) 536 ars = (CursorResultSet) ((TemporaryRowHolderResultSet) ars).clone(); 537 else if (ars instanceof TableScanResultSet) 538 ars = (CursorResultSet) ((TableScanResultSet) ars).clone(); 539 ars.open(); 540 java.sql.ResultSet rs = cc.getResultSet(ars); 541 resultSetVector.addElement(rs); 542 return rs; 543 } catch (StandardException se) 544 { 545 throw PublicAPI.wrapStandardException(se); 546 } 547 } 548 549 560 public java.sql.ResultSet getOldRow() throws SQLException 561 { 562 java.sql.ResultSet rs = getOldRowSet(); 563 if (rs != null) 564 rs.next(); 565 566 return rs; 567 } 568 569 580 public java.sql.ResultSet getNewRow() throws SQLException 581 { 582 java.sql.ResultSet rs = getNewRowSet(); 583 if (rs != null) 584 rs.next(); 585 return rs; 586 } 587 588 public Long getAutoincrementValue(String identity) 589 { 590 if (aiHT != null) 593 { 594 Long value = (Long )aiHT.get(identity); 595 if (value != null) 596 return value; 597 } 598 599 600 if (aiCounters != null) 603 { 604 for (int i = 0; i < aiCounters.size(); i++) 605 { 606 AutoincrementCounter aic = 607 (AutoincrementCounter)aiCounters.elementAt(i); 608 609 if (identity.equals(aic.getIdentity())) 611 { 612 return aic.getCurrentValue(); 614 } 615 } 616 } 617 618 return null; 620 } 621 625 public void copyHashtableToAIHT(Hashtable from) 626 { 627 if (from == null) 628 return; 629 if (aiHT == null) 630 aiHT = new Hashtable (); 631 for (Enumeration e = from.keys(); e.hasMoreElements(); ) 632 { 633 Object key = e.nextElement(); 634 Object value = from.get(key); 635 aiHT.put(key, value); 636 } 638 } 639 640 649 public void resetAICounters(boolean begin) 650 { 651 if (aiCounters == null) 652 return; 653 654 afterRow = null; 655 656 int size = aiCounters.size(); 657 for (int i = 0; i < size; i++) 658 { 659 AutoincrementCounter aic = 660 (AutoincrementCounter)aiCounters.elementAt(i); 661 aic.reset(begin); 662 } 663 } 664 665 669 public void updateAICounters() throws StandardException 670 { 671 if (aiCounters == null) 672 return; 673 674 int size = aiCounters.size(); 675 for (int i = 0; i < size; i++) 676 { 677 AutoincrementCounter aic = 678 (AutoincrementCounter)aiCounters.elementAt(i); 679 DataValueDescriptor dvd = afterRow.getColumn(aic.getColumnPosition()); 680 aic.update(dvd.getLong()); 681 } 682 } 683 684 685 public String toString() { 686 return triggerd.getName(); 687 } 688 689 690 } 691 | Popular Tags |