| 1 28 package com.lutris.dods.builder.generator.query; 29 30 import java.math.BigDecimal ; 31 import java.sql.PreparedStatement ; 32 import java.sql.ResultSet ; 33 import java.sql.SQLException ; 34 import java.util.BitSet ; 35 import java.util.Date ; 36 import java.util.Enumeration ; 37 import java.util.Hashtable ; 38 import java.util.Vector ; 39 40 import org.enhydra.dods.Common; 41 import org.enhydra.dods.CommonConstants; 42 import org.enhydra.dods.DODS; 43 import org.enhydra.dods.cache.CacheConstants; 44 45 import com.lutris.appserver.server.sql.CoreDataStruct; 46 import com.lutris.appserver.server.sql.DBConnection; 47 import com.lutris.appserver.server.sql.DBQuery; 48 import com.lutris.appserver.server.sql.DatabaseManagerException; 49 import com.lutris.appserver.server.sql.ExtendedDBConnection; 50 import com.lutris.appserver.server.sql.ExtendedQuery; 51 import com.lutris.appserver.server.sql.ObjectId; 52 import com.lutris.appserver.server.sql.ObjectIdException; 53 import com.lutris.appserver.server.sql.StandardDatabaseManager; 54 import com.lutris.appserver.server.sql.standard.DriverSpecificConstants; 55 import com.lutris.appserver.server.sql.standard.StandardLogicalDatabase; 56 import com.lutris.dods.builder.generator.dataobject.GenericDO; 57 import com.lutris.logging.Logger; 58 59 86 public class QueryBuilder implements ExtendedQuery { 87 private static final String OR = " OR "; 89 private static final String OPEN_PAREN = " ( "; 90 private static final String CLOSE_PAREN = " ) "; 91 public static final String EQUAL = "="; 93 public static String NOT_EQUAL = "!="; 94 public static final String LESS_THAN = "<"; 95 public static final String LESS_THAN_OR_EQUAL = "<="; 96 public static final String GREATER_THAN = ">"; 97 public static final String GREATER_THAN_OR_EQUAL = ">="; 98 public static final String IS_NULL = " IS NULL "; 99 public static final String IS_NOT_NULL = " IS NOT NULL "; 100 public static final String OPEN_IN = " IN ( "; 101 public static final String OPEN_NOT_IN = " NOT IN ( "; 102 public static final String OPEN_EXISTS = " EXISTS ( "; 103 public static final String OPEN_NOT_EXISTS = " NOT EXISTS ( "; 104 public static final String CLOSE_IN = " ) "; 105 public static final String CASE_SENSITIVE_CONTAINS = "%X%"; 106 public static final String CASE_INSENSITIVE_CONTAINS = "%x%"; 107 public static final String CASE_SENSITIVE_STARTS_WITH = "X%"; 108 public static final String CASE_INSENSITIVE_STARTS_WITH = "x%"; 109 public static final String CASE_SENSITIVE_ENDS_WITH = "%X"; 110 public static final String CASE_INSENSITIVE_ENDS_WITH = "%x"; 111 public static final String CASE_INSENSITIVE_EQUAL = "%xxxx"; 112 public static final String CASE_SENSITIVE_MATCH = "X"; 115 public static final String CASE_INSENSITIVE_MATCH = "x"; 116 public static final String USER_CASE_SENSITIVE_MATCH = "U"; 117 public static final String USER_CASE_INSENSITIVE_MATCH = "u"; 118 123 public static final boolean NULL_OK = true; 124 125 129 public static final boolean NOT_NULL = false; 130 131 135 public static final boolean EXACT_MATCH = true; 136 137 141 public static final boolean NOT_EXACT = false; 142 public static final String DEFAULT_MATCHES_KEYWORD = "MATCHES"; 144 private String likeKeyword = DEFAULT_MATCHES_KEYWORD; 145 public static final String DEFAULT_WILDCARD = "*"; 147 private String wildcard = DEFAULT_WILDCARD; 148 public static final String DEFAULT_SINGLE_WILDCARD = "_"; 153 public static final String DEFAULT_SINGLE_WILDCARD_ESCAPE = "?"; 154 public static final String DEFAULT_WILDCARD_ESCAPE = "?"; 155 public static final String DEFAULT_WILDCARD_ESCAPE_CLAUSE = "ESCAPE '?'"; 156 public static final String DEFAULT_USER_WILDCARD = "*"; 157 public static final String DEFAULT_USER_SINGLE_WILDCARD = "?"; 158 public static final String DEFAULT_USER_SINGLE_WILDCARD_ESCAPE = "?"; 159 public static final String DEFAULT_USER_WILDCARD_ESCAPE = "?"; 160 public static final boolean DEFAULT_USER_APPEND_WILDCARD = false; 161 public static final boolean DEFAULT_USER_TRIM_STRING = false; 162 public String userConfigWildcard = DEFAULT_USER_WILDCARD; 163 public String userConfigSingleWildcard = DEFAULT_USER_SINGLE_WILDCARD; 164 public String userConfigSingleWildcardEscape = DEFAULT_USER_SINGLE_WILDCARD_ESCAPE; 165 public String userConfigWildcardEscape = DEFAULT_USER_WILDCARD_ESCAPE; 166 static private boolean debugAllSQL = false; 169 private boolean debugSQL = false; 170 private boolean multiTableJoin = false; 172 private boolean unionTableJoin = false; 173 private boolean preventPrimaryKeySelect = false; 175 private int iCurrentFetchSize = -1; 178 private static int iDefaultFetchSize = -1; 179 private int iCurrentQueryTimeout = CacheConstants.DEFAULT_QUERY_TIMEOUT; 180 private static int iDefaultQueryTimeout = CacheConstants.DEFAULT_QUERY_TIMEOUT; 181 private String databaseName = null; 183 184 private int DEFAULT_RS_TYPE = -100; 185 private int DEFAULT_RS_CONCURRENCY = -100; 186 private int iResultSetConcurrency = DEFAULT_RS_CONCURRENCY; 187 private int iResultSetType = DEFAULT_RS_TYPE; 188 189 private String customNotEqualSqlOperator = null; 190 191 private boolean caseInsensitiveDatabase = CommonConstants.DEFAULT_CASE_INSENSITIVE_DATABASE; 192 193 279 280 287 public QueryBuilder(Vector fields) { 288 init(); 289 reset(); 290 if (null != fields) { 291 selectedFields = (Vector ) fields.clone(); 292 } 293 } 294 295 private void init(){ 296 try { 297 String value; 298 299 value=((StandardDatabaseManager)DODS.getDatabaseManager()) 300 .getDatabaseManagerConfiguration().getUserConfigWildcard(); 301 if (value!= null) { 302 userConfigWildcard = value; 303 } 304 305 value=((StandardDatabaseManager)DODS.getDatabaseManager()) 306 .getDatabaseManagerConfiguration().getUserConfigSingleWildcard(); 307 if (value!= null) { 308 userConfigSingleWildcard = value; 309 } 310 311 value=((StandardDatabaseManager)DODS.getDatabaseManager()) 312 .getDatabaseManagerConfiguration().getUserConfigSingleWildcardEscape(); 313 if (value!= null) { 314 userConfigSingleWildcardEscape = value; 315 } 316 } catch (Exception except) {} 317 initDefaultWildCards(); 318 319 try { 320 caseInsensitiveDatabase=((StandardLogicalDatabase)DODS.getDatabaseManager() 321 .findLogicalDatabase(getDatabaseName())).getDatabaseConfiguration().isCaseInsensitiveDatabase(); 322 } catch (Exception e) { 323 caseInsensitiveDatabase = CommonConstants.DEFAULT_CASE_INSENSITIVE_DATABASE; 324 } 325 326 customNotEqualSqlOperator = null; 327 try { 328 String customNotEqualSqlOperatorStr = ((StandardLogicalDatabase)DODS.getDatabaseManager() 329 .findLogicalDatabase(getDatabaseName())).getDriverProperty(DriverSpecificConstants.PARAMNAME_CUSTOM_NOT_EQUAL_SQL_OPERATOR); 330 if(customNotEqualSqlOperatorStr!=null) { 331 customNotEqualSqlOperator=customNotEqualSqlOperatorStr; 332 }else { 333 customNotEqualSqlOperator = DriverSpecificConstants.DEFAULT_CUSTOM_NOT_EQUAL_SQL_OPERATOR; 334 } 335 }catch(Exception e) {} 336 if(customNotEqualSqlOperator!=null) NOT_EQUAL=customNotEqualSqlOperator; 337 } 338 339 346 public QueryBuilder(RDBColumn[] fields) { 347 init(); 348 reset(); 349 for (int i = 0; i < fields.length; i++) { 350 select(fields[i]); 351 } 352 } 353 354 363 public QueryBuilder() { 364 init(); 365 reset(); 366 } 367 368 375 public void select(RDBColumn field) { 376 if (null == field) { 377 return; 378 } 379 for (int i = 0; i < selectedFields.size(); i++) { 380 if (field.equals((RDBColumn) selectedFields.elementAt(i))) { 381 return; 382 } 383 } 384 selectedFields.addElement(field); 385 } 386 387 396 public RDBRow[] getRows() 397 throws QueryException { 398 Vector v = new Vector (); 399 RDBRow row; 400 401 while (null != (row = getNextRow())) { 402 v.addElement(row); 403 } 404 RDBRow[] ret = new RDBRow[ v.size() ]; 405 406 v.copyInto(ret); 407 return ret; 408 } 409 410 423 private DBQuery dbQuery = null; 424 private ResultSet rs = null; 425 private Boolean rsClosed = null; 426 private boolean done = false; 427 public RDBRow getNextRow() throws QueryException { 428 if (done) { 429 return null; 430 } 431 if (null == rs) { 432 try { 433 if (null == dbQuery) { 434 dbQuery = DODS.getDatabaseManager().createQuery(); 437 } 438 } catch (Exception e) { 439 throw new QueryException("SQL=[" + sql 440 + "]: Unable to create query", 441 e); 442 } 443 try { 444 dbQuery.query(this); 446 } catch (Exception e) { 447 throw new QueryException("SQL=[" + sql 448 + "]: Unable to run query", 449 e); 450 } 451 if (null == rs) { 452 throw new QueryException("No ResultSet for Query."); 453 } 454 } 455 try { 456 if (!rs.next()) { 457 done = true; 462 rsClosed=new Boolean (true); 463 rs.close(); 464 dbQuery.release(); 465 return null; 466 } 467 } catch (Exception e) { 468 throw new QueryException("SQL=[" + sql 469 + "]: Unable to get query results", 470 e); 471 } 472 RDBColumnValue[] vals = new RDBColumnValue[ selectedFields.size() ]; 473 RDBColumn field = null; 474 475 for (int i = 0; i < selectedFields.size(); i++) { 476 try { 477 field = (RDBColumn) selectedFields.elementAt(i); 478 vals[i] = new RDBColumnValue(field, rs.getObject(i + 1)); 479 } catch (Exception e) { 480 throw new QueryException("SQL=[" + sql 481 + "]: Unable to get query result for column " + field, 482 e); 483 } 484 } 485 return new RDBRow(vals); 486 } 487 488 494 public Object next(ResultSet rs) 495 throws SQLException , ObjectIdException { 496 return null; 497 } 498 499 511 public QueryBuilder(String tableName) { 512 this(tableName, tableName + ".*"); 513 } 514 515 522 public QueryBuilder(String tableName, String fieldList) { 523 reset(); 524 init(); 525 526 mainTableName = tableName; 527 storeTableName(mainTableName); 528 selectClause = fieldList; 529 } 530 531 539 private String getTableName(String column) { 540 int offset = 0; 541 int end = 0; 542 String str = column; 543 int index = str.lastIndexOf("("); 544 545 if (-1 != index) { 546 str = str.substring(index + 1); 547 } 548 index = str.indexOf(")"); 549 if (-1 != index) { 550 str = str.substring(0, index); 551 } 552 index = str.indexOf("."); 553 if (-1 == index) { 554 return null; 555 } 556 return str.substring(0, index); 557 } 558 559 564 public boolean isMultiTableJoin() { 565 return multiTableJoin; 566 } 567 568 573 public boolean isUnionTableJoin() { 574 return unionTableJoin; 575 } 576 581 public boolean getPreventPrimaryKeySelect() { 582 return preventPrimaryKeySelect; 583 } 584 585 588 public void resetSelectedFields() { 589 selectedFields = new Vector (); 590 selectClause = ""; 591 } 592 593 599 private void storeTableNameForColumn(String column) { 600 String table = getTableName(column); 601 602 storeTableName(table); 603 } 604 605 611 private void storeTableNameForColumn(RDBColumn column) { 612 storeTableName(column.getTableName()); 613 } 614 615 621 private void storeTableName(String table) { 622 if (null != table) { 623 tableNames.put(table, ""); 624 } 625 } 626 627 649 public void addWhereOr() { 650 int n = whereClauses.size(); 651 652 if (0 == n) { 653 return; 654 } 655 String prev = (String ) whereClauses.lastElement(); 656 657 if (!OR.equals(prev)) { 658 whereClauses.addElement(OR); 659 } 660 } 661 662 669 public void addWhereOpenParen() { 670 whereClauses.addElement(OPEN_PAREN); 671 672 677 } 678 679 685 public void addWhereCloseParen() { 686 int n = whereClauses.size(); 687 688 if (0 == n) { 689 return; 690 } 691 String prev = (String ) whereClauses.lastElement(); 692 693 if (!(OR.equals(prev) || OPEN_PAREN.equals(prev))) { 694 whereClauses.addElement(CLOSE_PAREN); 695 } 696 } 697 698 706 public void addWhere(RDBColumn column, GenericDO value, String cmp_op) { 707 BigDecimal id = null; 708 709 if (null != value) { 710 id = value.get_OId().toBigDecimal(); 711 } 712 _addWhereClause(column, id, cmp_op); 713 } 714 715 723 public void addWhere(RDBColumn column, byte[] value, String cmp_op) { 724 String v = null; 725 726 if (null != value) { 727 v = new String (value); 728 } 729 _addWhereClause(column, v, cmp_op); 730 } 731 732 740 public void addWhere(RDBColumn column, java.sql.Time value, String cmp_op) { 741 _addWhereClause(column, value, cmp_op); 742 } 743 744 752 public void addWhere(RDBColumn column, java.sql.Timestamp value, String cmp_op) { 753 _addWhereClause(column, value, cmp_op); 754 } 755 756 764 public void addWhere(RDBColumn column, long value, String cmp_op) { 765 _addWhereClause(column, new Long (value), cmp_op); 766 } 767 768 776 public void addWhere(RDBColumn column, double value, String cmp_op) { 777 _addWhereClause(column, new Double (value), cmp_op); 778 } 779 780 788 public void addWhere(RDBColumn column, float value, String cmp_op) { 789 _addWhereClause(column, new Float (value), cmp_op); 790 } 791 792 800 public void addWhere(RDBColumn column, BigDecimal value, String cmp_op) { 801 _addWhereClause(column, value, cmp_op); 802 } 803 804 812 public void addWhere(RDBColumn column, int value, String cmp_op) { 813 |