1 26 27 package com.sqlmagic.tinysql; 28 29 import java.util.*; 30 import java.lang.*; 31 import java.io.*; 32 import java.sql.SQLException ; 33 import java.sql.Types ; 34 35 public class tinySQLWhere 36 { 37 Vector whereClauseList; 38 boolean debug=false; 39 42 public tinySQLWhere(String whereString) 43 { 44 FieldTokenizer ft; 45 Vector whereConditions; 46 Object whereObj; 47 String nextField,upperField,wherePhrase,comp,left,right,andOr; 48 String whereCondition[]; 49 String [] comparisons = {"<=","=<",">=","=>","=","<>","!=",">","<", 50 "LIKE","NOT LIKE"}; 51 boolean inBrackets=false; 52 int i,foundKeyWord,foundComp,startAt,foundAnd,foundOr; 53 57 whereConditions = new Vector(); 58 whereClauseList = new Vector(); 59 62 ft = new FieldTokenizer(whereString,'(',true); 63 while ( ft.hasMoreFields() ) 64 { 65 nextField = ft.nextField(); 66 upperField = nextField.toUpperCase(); 67 if ( nextField.equals("(") ) 68 { 69 whereObj = (Object )null; 70 inBrackets = true; 71 } else if ( nextField.equals(")") ) { 72 inBrackets = false; 73 whereObj = (Object )null; 74 } else if ( inBrackets ) { 75 whereObj = new tinySQLWhere(nextField); 76 whereConditions.addElement(whereObj); 77 } else { 78 82 andOr = "AND"; 83 startAt = 0; 84 whereConditions = new Vector(); 85 while ( startAt < upperField.length() ) 86 { 87 foundAnd = upperField.indexOf(" AND",startAt); 88 91 if ( foundAnd > -1 & foundAnd < upperField.length() - 5 ) 92 if ( upperField.charAt(foundAnd + 4) != ' ' ) 93 foundAnd = -1; 94 foundOr = upperField.indexOf(" OR",startAt); 95 if ( foundOr > -1 & foundOr < upperField.length() - 4 ) 96 if ( upperField.charAt(foundOr + 3) != ' ' ) 97 foundOr = -1; 98 foundKeyWord = upperField.length(); 99 if ( foundAnd > -1 ) foundKeyWord = foundAnd; 100 if ( foundOr > -1 & foundOr < foundKeyWord ) 101 foundKeyWord = foundOr; 102 wherePhrase = nextField.substring(startAt,foundKeyWord); 103 if ( debug ) 104 System.out.println("Where phrase is " + wherePhrase); 105 if ( foundKeyWord < upperField.length() - 4 ) 106 andOr = upperField.substring(foundKeyWord+1,foundKeyWord+3); 107 if ( andOr.equals("AN") ) andOr = "AND"; 108 122 whereCondition = new String [9]; 123 for ( i = 0; i < comparisons.length; i++ ) 124 { 125 comp = comparisons[i]; 126 foundComp = wherePhrase.toUpperCase().indexOf(comp); 127 if ( foundComp > -1 ) 128 { 129 whereCondition[0] = "JOIN"; 130 left = wherePhrase.substring(0,foundComp).trim(); 131 whereCondition[1] = left; 132 whereCondition[2] = comp; 133 right = wherePhrase.substring(foundComp + comp.length()).trim(); 134 whereCondition[3] = right; 135 whereCondition[8] = "UNKNOWN"; 136 break; 137 } 138 } 139 whereConditions.addElement(whereCondition); 140 145 if ( andOr.equals("OR") ) 146 { 147 whereClauseList.addElement(whereConditions); 148 whereConditions = new Vector(); 149 } 150 startAt = foundKeyWord + andOr.length() + 2; 151 } 152 } 153 } 154 157 if ( whereConditions.size() > 0 ) 158 whereClauseList.addElement(whereConditions); 159 if ( debug ) System.out.println("Where clause is \n" + toString()); 160 } 161 166 public void setColumnTypes(tinySQLTable inputTable ) throws tinySQLException 167 { 168 Hashtable ht = new Hashtable(); 169 Vector tableList = new Vector(); 170 tableList.addElement(inputTable.table); 171 ht.put(inputTable.table,inputTable); 172 ht.put("TABLE_SELECT_ORDER",tableList); 173 setColumnTypes(ht); 174 } 175 public void setColumnTypes(Hashtable tables) throws tinySQLException 176 { 177 int i,j,leftType,rightType,dotAt; 178 tinySQLTable leftTable,rightTable; 179 Vector whereConditions,selectTables; 180 Object whereObj; 181 boolean leftConstant,rightConstant; 182 String objectType,rightColumn,leftColumn,rightString,leftString; 183 String [] whereCondition; 184 selectTables = (Vector)tables.get("TABLE_SELECT_ORDER"); 185 for ( i = 0 ; i < whereClauseList.size(); i++ ) 186 { 187 whereConditions = (Vector)whereClauseList.elementAt(i); 188 for ( j = 0; j < whereConditions.size(); j++ ) 189 { 190 193 whereObj = whereConditions.elementAt(j); 194 objectType = whereObj.getClass().getName(); 195 if ( objectType.endsWith("tinySQLWhere") ) 196 { 197 ((tinySQLWhere)whereObj).setColumnTypes(tables); 198 } else if ( objectType.endsWith("java.lang.String;") ) { 199 whereCondition = (String [])whereObj; 200 leftColumn = whereCondition[1]; 201 leftString = whereCondition[5]; 202 206 leftTable = getTableForColumn(tables,leftColumn); 207 leftConstant = false; 208 if ( leftTable != (tinySQLTable)null ) 209 { 210 leftColumn = leftColumn.toUpperCase(); 211 leftType = leftTable.ColType(leftColumn); 212 dotAt = leftColumn.indexOf("."); 213 if ( dotAt > -1 ) leftColumn = leftColumn.substring(dotAt+1); 214 leftColumn = leftTable.table + "->" + leftTable.tableAlias 215 + "." + leftColumn; 216 whereCondition[1] = leftColumn; 217 } else { 218 222 if ( debug ) 223 System.out.println("No table found for " + leftColumn 224 + " - treat as constant"); 225 leftType = UtilString.getValueType(leftColumn); 226 leftString = UtilString.removeQuotes(leftColumn); 227 leftConstant = true; 228 } 229 rightColumn = whereCondition[3]; 230 rightString = whereCondition[7]; 231 rightTable = getTableForColumn(tables,rightColumn); 232 rightConstant = false; 233 if ( rightTable != (tinySQLTable)null ) 234 { 235 rightColumn = rightColumn.toUpperCase(); 236 rightType = rightTable.ColType(rightColumn); 237 dotAt = rightColumn.indexOf("."); 238 if ( dotAt > -1 ) 239 rightColumn = rightColumn.substring(dotAt+1); 240 rightColumn = rightTable.table + "->" 241 + rightTable.tableAlias + "." + rightColumn; 242 whereCondition[3] = rightColumn; 243 } else { 244 248 if ( debug ) 249 System.out.println("No table found for " 250 + rightColumn + " - treat as constant"); 251 rightType = UtilString.getValueType(rightColumn); 252 rightString = UtilString.removeQuotes(rightColumn); 253 rightConstant = true; 254 } 255 259 if ( Utils.isCharColumn(leftType) ) 260 { 261 if ( !Utils.isCharColumn(rightType) ) 262 throw new tinySQLException("Incompatible types: left is" 263 + " character but right is not."); 264 270 whereCondition[4] = "CHAR"; 271 if ( leftConstant ) 272 { 273 whereCondition[4] = "CHAR_CONSTANT"; 274 whereCondition[5] = leftString; 275 whereCondition[8] = "LEFT"; 276 if ( rightTable != (tinySQLTable)null ) 277 Utils.setPriority(selectTables,rightTable.table); 278 } 279 whereCondition[6] = "CHAR"; 280 if ( rightConstant ) 281 { 282 whereCondition[6] = "CHAR_CONSTANT"; 283 whereCondition[7] = rightString; 284 if ( whereCondition[8].equals("LEFT") ) 285 whereCondition[8] = "BOTH"; 286 else 287 whereCondition[8] = "RIGHT"; 288 if ( leftTable != (tinySQLTable)null ) 289 Utils.setPriority(selectTables,leftTable.table); 290 } 291 } else if ( Utils.isNumberColumn(leftType) ) { 292 if ( !Utils.isNumberColumn(rightType) ) 293 throw new tinySQLException("Incompatible types: left is " 294 + " numeric but right is not."); 295 whereCondition[4] = "NUMBER"; 296 if ( leftConstant ) 297 { 298 whereCondition[4] = "NUMBER_CONSTANT"; 299 whereCondition[5] = whereCondition[1]; 300 whereCondition[8] = "LEFT"; 301 } 302 whereCondition[6] = "NUMBER"; 303 if ( rightConstant ) 304 { 305 whereCondition[6] = "NUMBER_CONSTANT"; 306 whereCondition[7] = whereCondition[3]; 307 if ( whereCondition[8].equals("LEFT") ) 308 whereCondition[8] = "BOTH"; 309 else 310 whereCondition[8] = "RIGHT"; 311 } 312 } 313 } 314 } 315 } 316 } 317 320 public void clearValues(String inputTableName) 321 { 322 int i,j,dotAt; 323 Vector whereConditions; 324 Object whereObj; 325 String objectType,columnName,tableName; 326 String [] whereCondition; 327 StringBuffer outputBuffer = new StringBuffer (); 328 boolean conditionCleared; 329 for ( i = 0 ; i < whereClauseList.size(); i++ ) 330 { 331 whereConditions = (Vector)whereClauseList.elementAt(i); 332 for ( j = 0; j < whereConditions.size(); j++ ) 333 { 334 337 whereObj = whereConditions.elementAt(j); 338 objectType = whereObj.getClass().getName(); 339 conditionCleared = false; 340 if ( objectType.endsWith("tinySQLWhere") ) 341 { 342 ((tinySQLWhere)whereObj).clearValues(inputTableName); 343 } else if ( objectType.endsWith("java.lang.String;") ) { 344 whereCondition = (String [])whereObj; 345 if ( whereCondition[8].equals("UNKNOWN") ) continue; 346 349 dotAt = whereCondition[1].indexOf("."); 350 if ( !whereCondition[4].endsWith("CONSTANT") & dotAt > -1 ) 351 { 352 tableName = whereCondition[1].substring(0,dotAt); 353 if ( tableName.equals(inputTableName) ) 354 { 355 whereCondition[5] = (String )null; 356 if ( whereCondition[8].equals("LEFT") ) 357 whereCondition[8] = "UNKNOWN"; 358 else 359 whereCondition[8] = "RIGHT"; 360 conditionCleared = true; 361 } 362 } 363 366 dotAt = whereCondition[3].indexOf("."); 367 if ( !whereCondition[6].endsWith("CONSTANT") & dotAt > -1 ) 368 { 369 tableName = whereCondition[3].substring(0,dotAt); 370 if ( tableName.equals(inputTableName) ) 371 { 372 whereCondition[7] = (String )null; 373 if ( whereCondition[8].equals("RIGHT") ) 374 whereCondition[8] = "UNKNOWN"; 375 else 376 whereCondition[8] = "LEFT"; 377 conditionCleared = true; 378 } 379 } 380 if ( debug & conditionCleared ) 381 System.out.println("Where condition after clearing " 382 + inputTableName + " is\n" + conditionToString(whereCondition)); 383 } 384 } 385 } 386 } 387 public String toString() 388 { 389 int i,j; 390 Vector whereConditions; 391 Object whereObj; 392 String objectType; 393 String [] whereCondition; 394 StringBuffer outputBuffer = new StringBuffer (); 395 for ( i = 0 ; i < whereClauseList.size(); i++ ) 396 { 397 if ( i > 0 ) outputBuffer.append("OR\n"); 398 whereConditions = (Vector)whereClauseList.elementAt(i); 399 for ( j = 0; j < whereConditions.size(); j++ ) 400 { 401 if ( j > 0 ) outputBuffer.append("AND\n"); 402 405 whereObj = whereConditions.elementAt(j); 406 objectType = whereObj.getClass().getName(); 407 if ( objectType.endsWith("tinySQLWhere") ) 408 { 409 outputBuffer.append(((tinySQLWhere)whereObj).toString()); 410 } if ( objectType.endsWith("java.lang.String;") ) { 411 whereCondition = (String [])whereObj; 412 outputBuffer.append(conditionToString(whereCondition) + "\n"); 413 } 414 } 415 } 416 return outputBuffer.toString(); 417 } 418 421 private String conditionToString(String [] inputWhereCondition) 422 { 423 int i; 424 StringBuffer outputBuffer = new StringBuffer ();; 425 for ( i = 0; i < 9; i++ ) 426 { 427 if ( inputWhereCondition[i] == (String )null ) 428 outputBuffer.append(" NULL "); 429 else 430 outputBuffer.append(" " + inputWhereCondition[i] + " "); 431 } 432 return outputBuffer.toString(); 433 } 434 435 439 private tinySQLTable getTableForColumn(Hashtable tables, String inputColumn) 440 { 441 tinySQLTable tbl; 442 Vector tableNames; 443 Hashtable columnInfo; 444 String findColumn,tableAndAlias=(String )null,tableAlias; 445 int i,dotAt; 446 findColumn = inputColumn.toUpperCase(); 447 dotAt = findColumn.indexOf("."); 448 tableNames = (Vector)tables.get("TABLE_SELECT_ORDER"); 449 if ( dotAt > -1 ) 450 { 451 tableAlias = findColumn.substring(0,dotAt); 452 try 453 { 454 tableAndAlias = UtilString.findTableAlias(tableAlias,tableNames); 455 } catch (Exception ex ) { 456 } 457 if ( tableAndAlias != (String )null ) 458 { 459 tbl = (tinySQLTable)tables.get(tableAndAlias); 460 if ( tbl != (tinySQLTable)null ) return tbl; 461 } 462 } else { 463 for ( i = 0; i < tableNames.size(); i++ ) 464 { 465 tbl = (tinySQLTable)tables.get((String )tableNames.elementAt(i)); 466 470 columnInfo = tbl.column_info; 471 if ( columnInfo != (Hashtable)null ) 472 if (columnInfo.containsKey(findColumn)) return tbl; 473 } 474 } 475 return (tinySQLTable)null; 476 } 477 481 public String evaluate(String inputColumnName,String inputColumnValue) 482 throws tinySQLException 483 { 484 int i,j,k; 485 FieldTokenizer ft; 486 Vector whereConditions; 487 Object whereObj; 488 String objectType,leftString,rightString,comparison,conditionStatus, 489 nextField; 490 String [] whereCondition; 491 boolean like,whereUpdated; 492 double leftValue, rightValue; 493 for ( i = 0 ; i < whereClauseList.size(); i++ ) 494 { 495 whereConditions = (Vector)whereClauseList.elementAt(i); 496 for ( j = 0; j < whereConditions.size(); j++ ) 497 { 498 501 conditionStatus = "TRUE"; 502 whereObj = whereConditions.elementAt(j); 503 objectType = whereObj.getClass().getName(); 504 whereUpdated = false; 505 if ( objectType.endsWith("tinySQLWhere") ) 506 { 507 conditionStatus =((tinySQLWhere)whereObj).evaluate(inputColumnName,inputColumnValue); 508 } else if ( objectType.endsWith("java.lang.String;") ) { 509 whereCondition = (String [])whereObj; 510 514 if ( inputColumnName.equals(whereCondition[1]) ) 515 { 516 whereUpdated = true; 517 whereCondition[5] = inputColumnValue.trim(); 518 if ( whereCondition[8].equals("UNKNOWN") ) 519 whereCondition[8] = "LEFT"; 520 else if ( whereCondition[8].equals("RIGHT") ) 521 whereCondition[8] = "BOTH"; 522 } else if ( inputColumnName.equals(whereCondition[3]) ) { 523 whereUpdated = true; 524 whereCondition[7] = inputColumnValue.trim(); 525 if ( whereCondition[8].equals("UNKNOWN") ) 526 whereCondition[8] = "RIGHT"; 527 else if ( whereCondition[8].equals("LEFT") ) 528 whereCondition[8] = "BOTH"; 529 } 530 if ( !whereUpdated ) continue; 531 if ( debug ) System.out.println("Where condition update to " 532 + inputColumnName + "\n" + conditionToString(whereCondition)); 533 537 if ( whereCondition[8].equals("UNKNOWN") | 538 whereCondition[8].equals("LEFT") | 539 whereCondition[8].equals("RIGHT") ) continue; 540 543 leftString = whereCondition[5]; 544 rightString = whereCondition[7]; 545 comparison = whereCondition[2]; 546 if ( whereCondition[4].startsWith("CHAR") ) 547 { 548 if ( comparison.equals("=") & 549 !leftString.equals(rightString) ) { 550 conditionStatus = "FALSE"; 551 } else if ( comparison.equalsIgnoreCase("LIKE") ) { 552 ft = new FieldTokenizer(rightString,'%',false); 553 like = false; 554 while ( ft.hasMoreFields() ) 555 { 556 nextField = ft.nextField(); 557 if ( leftString.indexOf(nextField) > -1 ) 558 like = true; 559 } 560 if ( !like ) conditionStatus = "FALSE"; 561 } else if ( comparison.equals("<>") & 562 leftString.equals(rightString) ) { 563 conditionStatus = "FALSE"; 564 } else if ( comparison.equals("!=") & 565 leftString.equals(rightString) ) { 566 conditionStatus = "FALSE"; 567 } else if ( comparison.equals(">") & 568 leftString.compareTo(rightString) <= 0 ) { 569 conditionStatus = "FALSE"; 570 } else if ( comparison.equals("<") & 571 leftString.compareTo(rightString) >= 0 ) { 572 conditionStatus = "FALSE"; 573 } 574 } else if ( whereCondition[4].startsWith("NUMBER") ) { 575 578 try 579 { 580 leftValue = Double.parseDouble(leftString); 581 } catch (Exception e) { 582 throw new tinySQLException( e.getMessage() + 583 ": Could not convert [" + leftString + "] to numeric."); 584 } 585 try 586 { 587 rightValue = Double.parseDouble(rightString); 588 } catch (Exception e) { 589 throw new tinySQLException( e.getMessage() + 590 ": Could not convert [" + rightString + "] to numeric."); 591 } 592 595 if (comparison.equals("=") & leftValue != rightValue) 596 conditionStatus = "FALSE"; 597 else if (comparison.equals("<>") & leftValue == rightValue) 598 conditionStatus = "FALSE"; 599 else if (comparison.equals(">") & leftValue <= rightValue) 600 conditionStatus = "FALSE"; 601 else if (comparison.equals("<") & leftValue >= rightValue) 602 conditionStatus = "FALSE"; 603 else if (comparison.equals("<=") & leftValue > rightValue) 604 conditionStatus = "FALSE"; 605 else if (comparison.equals("=<") & leftValue > rightValue) 606 conditionStatus = "FALSE"; 607 else if (comparison.equals(">=") & leftValue < rightValue) 608 conditionStatus = "FALSE"; 609 else if (comparison.equals("=>") & leftValue < rightValue) 610 conditionStatus = "FALSE"; 611 } 612 whereCondition[8] = conditionStatus; 613 if ( debug ) System.out.println("Where condition evaluation:\n" 614 + conditionToString(whereCondition)); 615 } 616 } 617 } 618 return getStatus(); 619 } 620 623 public String getStatus() 624 { 625 int i,j; 626 Vector whereConditions; 627 Object whereObj; 628 String objectType,andStatus,orStatus; 629 String [] whereCondition; 630 orStatus = "FALSE"; 631 for ( i = 0 ; i < whereClauseList.size(); i++ ) 632 { 633 636 whereConditions = (Vector)whereClauseList.elementAt(i); 637 andStatus = "TRUE"; 638 for ( j = 0; j < whereConditions.size(); j++ ) 639 { 640 643 whereObj = whereConditions.elementAt(j); 644 objectType = whereObj.getClass().getName(); 645 if ( objectType.endsWith("tinySQLWhere") ) 646 { 647 andStatus = ((tinySQLWhere)whereObj).getStatus(); 648 if ( andStatus.equals("FALSE")) break; 649 } else if ( objectType.endsWith("java.lang.String;") ) { 650 whereCondition = (String [])whereObj; 651 655 if ( whereCondition[8].equals("FALSE") ) 656 { 657 andStatus = "FALSE"; 658 break; 659 663 } else if ( whereCondition[8].equals("UNKNOWN") | 664 whereCondition[8].equals("LEFT") | 665 whereCondition[8].equals("RIGHT") ) { 666 andStatus = "UNKNOWN"; 667 } 668 } 669 } 670 674 if ( andStatus.equals("TRUE") ) 675 { 676 orStatus = "TRUE"; 677 break; 678 } else if ( andStatus.equals("UNKNOWN") ) { 679 orStatus = "UNKNOWN"; 680 } 681 } 682 if ( debug ) System.out.println("Return status " + orStatus); 683 return orStatus; 684 } 685 } 686 | Popular Tags |