| 1 2 38 39 package jspPhoneBook.data; 40 41 import org.enhydra.dods.DODS; 42 import com.lutris.dods.builder.generator.query.*; 43 import com.lutris.appserver.server.sql.*; 44 import org.enhydra.dods.cache.LRUCache; 45 import org.enhydra.dods.cache.DataStructCache; 46 import org.enhydra.dods.cache.QueryCache; 47 import org.enhydra.dods.cache.QueryCacheItem; 48 import org.enhydra.dods.cache.QueryResult; 49 import org.enhydra.dods.cache.DataStructShell; 50 import org.enhydra.dods.cache.DOShell; 51 import org.enhydra.dods.cache.Condition; 52 import org.enhydra.dods.statistics.Statistics; 53 import org.enhydra.dods.cache.CacheConstants; 54 import org.enhydra.dods.statistics.*; 55 import com.lutris.logging.LogChannel; 56 import com.lutris.logging.Logger; 57 import com.lutris.appserver.server.sql.standard.StandardDBTransaction; 58 59 import java.sql.*; 60 import java.util.*; 61 import java.math.*; 62 import java.util.Date ; 64 122 public class PersonQuery implements Query { 123 124 private QueryBuilder builder; 125 126 129 private String logicalDatabase; 130 131 private ResultSet resultSet = null; 132 private boolean uniqueInstance = false; 133 private boolean loadData = false; 134 private PersonDO[] DOs = null; 135 private int arrayIndex = -1; 136 private boolean needToRun = true; 137 private LinkedHashMap cacheHits = null; 138 private boolean isQueryByOId = false; 139 private boolean hasNonOidCond = false; 140 private boolean hitDb = false; 141 private boolean userHitDb = false; 142 private int maxDBrows = 0; 143 private boolean orderRelevant = true; private QueryCacheItem queryItem = null; 145 private String currentHandle = null; 146 private HashMap refs = new HashMap(); 147 private int iCurrentFetchSize = -1; 148 private int iCurrentQueryTimeout = 0; 149 private DBTransaction transaction = null; 150 151 156 public PersonQuery() { 157 158 builder = new QueryBuilder( "person", "person.*" ); 159 160 String dbName = PersonDO.get_logicalDBName(); 161 try { 162 String vendor = DODS.getDatabaseManager().logicalDatabaseType(dbName); 163 if (vendor != null) { 164 builder.setDatabaseVendor(vendor); 165 logicalDatabase = dbName; 166 } else { 167 builder.setDatabaseVendor(); 168 logicalDatabase = DODS.getDatabaseManager().getDefaultDB(); 169 } 170 } catch (Exception e) { 171 builder.setDatabaseVendor(); 172 logicalDatabase = DODS.getDatabaseManager().getDefaultDB(); 173 } 174 builder.setUserStringAppendWildcard( false ); 175 builder.setUserStringTrim( false ); 176 reset(); 177 } 178 179 184 public PersonQuery(DBTransaction dbTrans) { 185 186 builder = new QueryBuilder( "person", "person.*" ); 187 188 String dbName = null; 189 if(dbTrans!=null) 190 dbName = dbTrans.getDatabaseName(); 191 else 192 dbName = PersonDO.get_logicalDBName(); 193 try { 194 transaction = dbTrans; 195 String vendor = DODS.getDatabaseManager().logicalDatabaseType(dbName); 196 if (vendor != null) { 197 builder.setDatabaseVendor(vendor); 198 logicalDatabase = dbName; 199 } else { 200 builder.setDatabaseVendor(); 201 logicalDatabase = DODS.getDatabaseManager().getDefaultDB(); 202 } 203 } catch (Exception e) { 204 builder.setDatabaseVendor(); 205 logicalDatabase = DODS.getDatabaseManager().getDefaultDB(); 206 } 207 builder.setUserStringAppendWildcard( false ); 208 builder.setUserStringTrim( false ); 209 reset(); 210 } 211 212 213 214 220 public String getLogicalDatabase() { 221 return logicalDatabase; 222 } 223 224 230 public void setLogicalDatabase(String dbName) throws SQLException, DatabaseManagerException { 231 String vendor = DODS.getDatabaseManager().logicalDatabaseType(dbName); 232 if (vendor != null) { 233 builder.setDatabaseVendor(vendor); 234 logicalDatabase = dbName; 235 } else { 236 builder.setDatabaseVendor(); 237 logicalDatabase = DODS.getDatabaseManager().getDefaultDB(); 238 } 239 reset(); 240 } 241 242 243 244 private boolean unique = false; 247 248 256 public void setUnique(boolean newUnique) { unique = newUnique; } 257 258 266 public boolean getUnique() { return unique; } 267 268 private int readSkip = 0; 271 272 280 public void setReadSkip(int newReadSkip) { 281 readSkip = newReadSkip; 282 } 283 284 292 public int getReadSkip() { return readSkip; } 293 294 private int databaseLimit = 0; 297 298 306 public void setDatabaseLimit(int newLimit) { 307 databaseLimit = newLimit; 308 } 309 310 318 public int getDatabaseLimit() { return databaseLimit; } 319 320 private boolean databaseLimitExceeded = false; 321 322 330 public boolean getDatabaseLimitExceeded() { return databaseLimitExceeded; } 331 333 336 public void hitDatabase() { userHitDb = true; } 337 338 341 348 public void setUserStringWildcard(String newUserStringWildcard) { 349 builder.setUserStringWildcard( newUserStringWildcard ); 350 } 351 352 359 public void setUserStringSingleWildcard(String newUserStringSingleWildcard) { 360 builder.setUserStringSingleWildcard( newUserStringSingleWildcard ); 361 } 362 363 370 public void setUserStringSingleWildcardEscape(String newUserStringSingleWildcardEscape) { 371 builder.setUserStringSingleWildcardEscape( newUserStringSingleWildcardEscape ); 372 } 373 374 381 public void setUserStringWildcardEscape(String newUserStringWildcardEscape) { 382 builder.setUserStringWildcardEscape( newUserStringWildcardEscape ); 383 } 384 385 392 public void setUserStringAppendWildcard(boolean userStringAppendWildcard ) { 393 builder.setUserStringAppendWildcard( userStringAppendWildcard ); 394 } 395 396 403 public void setUserStringTrim(boolean userStringTrim ) { 404 builder.setUserStringTrim( userStringTrim ); 405 } 406 407 414 public String getUserStringWildcard() { 415 return builder.getUserStringWildcard(); 416 } 417 418 425 public String getUserStringSingleWildcard() { 426 return builder.getUserStringSingleWildcard(); 427 } 428 429 436 public String getUserStringSingleWildcardEscape() { 437 return builder.getUserStringSingleWildcardEscape(); 438 } 439 440 447 public String getUserStringWildcardEscape() { 448 return builder.getUserStringWildcardEscape(); 449 } 450 451 458 public boolean getUserStringAppendWildcard() { 459 return builder.getUserStringAppendWildcard(); 460 } 461 462 469 public boolean getUserStringTrim() { 470 return builder.getUserStringTrim(); 471 } 472 474 481 private void getQueryByOIds(Vector DOs) 482 throws DataObjectException { 483 if (DOs.size() == 0) 484 return; 485 PersonDO DO = null; 486 DOShell shell = null; 487 PersonQuery tmpQuery = null; 488 Date startQueryTime = new Date (); 489 long queryTime = 0; 490 for (int i=0; i<DOs.size(); i++) { 491 shell = (DOShell)DOs.elementAt(i); 492 tmpQuery = new PersonQuery(transaction); 493 try { 494 tmpQuery.setQueryHandle( shell.handle ); 495 tmpQuery.requireUniqueInstance(); 496 497 DO = tmpQuery.getNextDO(); 498 if ( null == DO ) 499 throw new DataObjectException("PersonDO DO not found for id=" + shell.handle ); 500 } catch ( Exception e ) { 501 throw new DataObjectException( "Duplicate ObjectId" ); 502 } 503 shell.dataObject = DO; 504 } 505 Date stopQueryTime = new Date (); 506 queryTime = stopQueryTime.getTime() - startQueryTime.getTime(); 507 PersonDO.statistics.updateQueryByOIdAverageTime((new Long (queryTime)).intValue(),DOs.size()); 508 } 509 510 511 512 519 private void runQuery() 520 throws DataObjectException, NonUniqueQueryException { 521 needToRun = false; 522 arrayIndex = -1; 523 DBQuery dbQuery = null; 524 Date startQueryTime = new Date (); 525 long queryTime = 0; 526 boolean readDOs = false; 527 boolean canUseQueryCache = true; 528 CacheStatistics stat = null; 529 boolean resultsFromQCache = false; 530 QueryCacheItem queryCachedItem = null; 531 532 if ((transaction!=null) && 533 (transaction instanceof com.lutris.appserver.server.sql.standard.StandardDBTransaction)) { 534 if(((com.lutris.appserver.server.sql.standard.StandardDBTransaction)transaction).getAutoWrite()) try { 535 transaction.write(); 536 } catch (SQLException sqle) { 537 sqle.printStackTrace(); 538 throw new DataObjectException("Couldn't write transaction: "+sqle); 539 } 540 ((com.lutris.appserver.server.sql.standard.StandardDBTransaction)transaction).dontAggregateDOModifications(); 541 } 542 543 try { 544 QueryResult results = null; 545 DOShell shell = null; 546 if (isQueryByOId && !hasNonOidCond) { results = new QueryResult(); 548 if (currentHandle != null) { 549 if(transaction!=null && _tr_(transaction).getTransactionCache()!=null && !loadData) { 550 PersonDO DO= (PersonDO)_tr_(transaction).getTransactionCache().getDOByHandle(currentHandle); 551 if(DO!=null){ 552 shell = new DOShell(DO); 553 results.DOs.add(shell); 554 resultsFromQCache = true; 555 } 556 else 557 resultsFromQCache = false; 558 } 559 if(!resultsFromQCache) { PersonDataStruct DS = (PersonDataStruct)PersonDO.cache.getDataStructByHandle(currentHandle); 561 if (DS != null) { PersonDO DO = (PersonDO)PersonDO.createExisting(DS.get_OId(), transaction); 563 shell = new DOShell(DO); 564 results.DOs.add(shell); 565 resultsFromQCache = true; 566 }else{ if (PersonDO.cache.isFull()) 568 resultsFromQCache = false; 569 } 570 } 571 } } 573 else { if ((PersonDO.cache.isFull()) && (!hitDb)) { 575 resultsFromQCache = true; 576 } 577 else { 578 if (PersonDO.cache.getLevelOfCaching() == CacheConstants.QUERY_CACHING) { 579 if (hitDb) { stat = null; 581 stat = PersonDO.statistics.getCacheStatistics(CacheConstants.COMPLEX_QUERY_CACHE); 582 if (stat!= null){ 583 stat.incrementCacheAccessNum(1); 584 } 585 }else{ stat = null; 587 stat = PersonDO.statistics.getCacheStatistics(CacheConstants.SIMPLE_QUERY_CACHE); 588 if (stat!= null){ 589 stat.incrementCacheAccessNum(1); 590 } 591 } 592 } 593 if(transaction != null) 594 canUseQueryCache = !transaction.preventCacheQueries(); 595 if ((PersonDO.cache.getLevelOfCaching() == CacheConstants.QUERY_CACHING) && canUseQueryCache) { 596 String queryID = builder.getSQLwithParms(); int resNum = 0; 598 int evaluateNo = 0; 599 if (hitDb) 600 queryCachedItem = ((QueryCache)PersonDO.cache).getComplexQueryCacheItem(logicalDatabase, queryID); 601 else 602 queryCachedItem = ((QueryCache)PersonDO.cache).getSimpleQueryCacheItem(logicalDatabase, queryID); 603 queryItem.setQueryId(queryID); if (queryCachedItem == null) { if ((!builder.isMultiTableJoin()) || PersonDO.isAllReadOnly()) { 606 if (hitDb) 607 ((QueryCache)PersonDO.cache).addComplexQuery(queryItem); else 609 ((QueryCache)PersonDO.cache).addSimpleQuery(queryItem); } 611 }else{ if ( !(isOrderRelevant() && queryCachedItem.isModifiedQuery()) ) { 613 if (hitDb) { stat = null; 615 stat = PersonDO.statistics.getCacheStatistics(CacheConstants.COMPLEX_QUERY_CACHE); 616 if (stat!= null){ 617 stat.incrementCacheHitsNum(1); 618 } 619 }else{ stat = null; 621 stat = PersonDO.statistics.getCacheStatistics(CacheConstants.SIMPLE_QUERY_CACHE); 622 if (stat!= null){ 623 stat.incrementCacheHitsNum(1); 624 } 625 } 626 627 int limitOfRes; 628 if (databaseLimit == 0) 629 limitOfRes = 0; 630 else 631 limitOfRes = readSkip+databaseLimit+1; 632 if (! unique) { 633 if (hitDb) 634 results = ((QueryCache)PersonDO.cache).getComplexQueryResults(logicalDatabase, queryID, limitOfRes, maxDBrows); 635 else 636 results = ((QueryCache)PersonDO.cache).getSimpleQueryResults(logicalDatabase, queryID, limitOfRes, maxDBrows); 637 }else{ if (hitDb) 639 results = ((QueryCache)PersonDO.cache).getComplexQueryResults(logicalDatabase, queryID, limitOfRes, maxDBrows, true); 640 else 641 results = ((QueryCache)PersonDO.cache).getSimpleQueryResults(logicalDatabase, queryID, limitOfRes, maxDBrows, true); 642 } if (results != null) { 644 results = getCachedResults(results); 646 resNum = results.DOs.size(); 647 if (databaseLimit != 0) { if (resNum == readSkip+databaseLimit+1) { 649 resNum--; 650 databaseLimitExceeded = true; 651 results.DOs.remove(readSkip+databaseLimit); 652 }else{ 653 if ( (resNum == readSkip+databaseLimit) && (!queryCachedItem.isCompleteResult()) ) 654 databaseLimitExceeded = true; 655 } 656 } if ( (databaseLimit!=0 &&(resNum == (readSkip+databaseLimit))) || (maxDBrows!=0 && (resNum + results.skippedUnique) == maxDBrows) || (queryCachedItem.isCompleteResult()) ) { 658 int lazyTime = PersonDO.statistics.getQueryByOIdAverageTime()*results.lazy.size(); 659 if (lazyTime <= queryCachedItem.getTime()) { 660 resultsFromQCache = true; 661 getQueryByOIds(results.lazy); }else 663 databaseLimitExceeded = false; 664 }else 665 databaseLimitExceeded = false; 666 } 668 } } } } } if (( userHitDb) || (!resultsFromQCache)) { 675 dbQuery = PersonDO.createQuery(transaction); 676 677 results = new QueryResult(); 678 int resultCount=0; 679 boolean bHasMoreResults = false; 680 if (( (PersonDO.getConfigurationAdministration().getTableConfiguration().isLazyLoading()) || isCaching()) && (!builder.getPreventPrimaryKeySelect()) && !loadData) { 681 builder.resetSelectedFields(); 682 builder.setSelectClause("person."+PersonDO.get_OIdColumnName()+", person."+PersonDO.get_versionColumnName()); 683 } 684 else 685 builder.setSelectClause( "person.*"); 686 dbQuery.query( this ); 688 689 if (! unique) { 690 while ( (bHasMoreResults = resultSet.next()) && (databaseLimit==0 || (results.DOs.size()<databaseLimit)) ) { 691 PersonDO newDO; 692 PersonDataStruct newDS; 693 694 if (( (PersonDO.getConfigurationAdministration().getTableConfiguration().isLazyLoading()) || isCaching()) && (!builder.getPreventPrimaryKeySelect()) && !loadData) { 695 newDO = PersonDO.createExisting ( new ObjectId(resultSet.getBigDecimal(CoreDO.get_OIdColumnName())) , refs, transaction); 696 newDO.set_Version(resultSet.getInt(PersonDO.get_versionColumnName())); 697 } else 698 newDO = PersonDO.createExisting ( resultSet , refs, transaction); 699 if(transaction==null) { 700 if(newDO!=null && newDO.isTransactionCheck()) { 701 String trace=""; 702 StackTraceElement [] traceElements= (new Throwable ()).getStackTrace(); 703 for(int i=0; i < traceElements.length; i++) 704 trace+=traceElements[i].toString()+"\n"; 705 DODS.getLogChannel().write(Logger.WARNING, "DO without transaction context is created : Database: "+newDO.get_OriginDatabase()+" PersonDO class, oid: "+newDO.get_OId()+", version: "+newDO.get_Version()+" \n"+trace); 706 } 707 } 708 709 if (queryItem != null) { 710 queryItem.add((PersonDataStruct)newDO.originalData_get()); 711 } 712 if (( (PersonDO.getConfigurationAdministration().getTableConfiguration().isLazyLoading()) || isCaching()) && (!builder.getPreventPrimaryKeySelect()) && !loadData) 713 {} 714 else 715 newDS =PersonDO.addToCache((PersonDataStruct)newDO.originalData_get()); 716 717 if (resultCount >= readSkip) { 718 shell = new DOShell(newDO); 719 results.DOs.add(shell); 720 } 721 resultCount++; 722 723 } } 726 else { HashSet hsResult = new HashSet(readSkip+databaseLimit); 728 while((bHasMoreResults = resultSet.next()) && (databaseLimit==0 || (results.DOs.size()<databaseLimit)) ) { 729 PersonDO newDO; 730 PersonDataStruct newDS; 731 732 if (( (PersonDO.getConfigurationAdministration().getTableConfiguration().isLazyLoading()) || isCaching()) && (!builder.getPreventPrimaryKeySelect()) && !loadData) { 733 newDO = PersonDO.createExisting ( new ObjectId(resultSet.getBigDecimal(CoreDO.get_OIdColumnName())) , refs, transaction); 734 newDO.set_Version(resultSet.getInt(PersonDO.get_versionColumnName())); 735 } else 736 newDO = PersonDO.createExisting ( resultSet , refs , transaction); 737 if(transaction==null) { 738 if(newDO!=null && newDO.isTransactionCheck()) { 739 String trace=""; 740 StackTraceElement [] traceElements= (new Throwable ()).getStackTrace(); 741 for(int i=0; i < traceElements.length; i++) 742 trace+=traceElements[i].toString()+"\n"; 743 DODS.getLogChannel().write(Logger.WARNING, "DO without transaction context is created : Database: "+newDO.get_OriginDatabase()+" PersonDO class, oid: "+newDO.get_OId()+", version: "+newDO.get_Version()+" \n"+trace); 744 } 745 } 746 747 if (queryItem != null) { 748 queryItem.add((PersonDataStruct)newDO.originalData_get()); 749 } 750 if (( (PersonDO.getConfigurationAdministration().getTableConfiguration().isLazyLoading()) || isCaching()) && (!builder.getPreventPrimaryKeySelect()) && !loadData) 751 { 752 } else 753 newDS = PersonDO.addToCache((PersonDataStruct)newDO.originalData_get()); 754 755 if (!hsResult.contains(newDO.get_Handle())) { 756 hsResult.add(newDO.get_Handle()); 757 if (resultCount >= readSkip) { 758 759 shell = new DOShell(newDO); 760 results.DOs.add(shell); 761 } 762 resultCount++; 763 } 764 765 } } 768 if ((results.DOs.size()==databaseLimit)&& bHasMoreResults) { 769 resultSet.close(); 770 databaseLimitExceeded = true; 771 } 772 if (maxDBrows > 0) { 773 if (!bHasMoreResults) { 774 if ((databaseLimit > 0) && databaseLimit < maxDBrows ) 775 queryItem.setCompleteResult(true); 776 &nbs
|