src/org/objectweb/cjdbc/common/sql/SelectRequest.java

説明を見る。
00001 00025 package org.objectweb.cjdbc.common.sql; 00026 00027 import java.io.Serializable; 00028 import java.sql.SQLException; 00029 import java.util.ArrayList; 00030 import java.util.Hashtable; 00031 import java.util.Iterator; 00032 import java.util.StringTokenizer; 00033 00034 import org.objectweb.cjdbc.common.sql.schema.AliasedDatabaseTable; 00035 import org.objectweb.cjdbc.common.sql.schema.DatabaseColumn; 00036 import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema; 00037 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable; 00038 import org.objectweb.cjdbc.common.sql.schema.TableColumn; 00039 00063 public class SelectRequest extends AbstractRequest implements Serializable 00064 { 00066 private transient ArrayList select; 00067 00069 private transient ArrayList from; 00070 00072 private transient ArrayList aliasFrom; 00073 00075 private transient ArrayList where; 00076 00078 private transient ArrayList order; 00079 00081 public static final int NO_FUNCTION = 0; 00083 public static final int MAX_FUNCTION = 1; 00085 public static final int MIN_FUNCTION = 2; 00087 public static final int AVERAGE_FUNCTION = 3; 00089 public static final int COUNT_FUNCTION = 4; 00091 public static final int SUM_FUNCTION = 5; 00092 00094 public transient int funcType = 0; 00095 00097 private transient String pkValue; 00098 00108 private transient Hashtable whereValues; 00109 00110 private String cursorName = null; 00111 00133 public SelectRequest(String sqlQuery, boolean escapeProcessing, int timeout, 00134 String lineSeparator, DatabaseSchema schema, int granularity, 00135 boolean isCaseSensitive) throws SQLException 00136 { 00137 this(sqlQuery, escapeProcessing, timeout, lineSeparator); 00138 parse(schema, granularity, isCaseSensitive); 00139 } 00140 00156 public SelectRequest(String sqlQuery, boolean escapeProcessing, int timeout, 00157 String lineSeparator) 00158 { 00159 super(sqlQuery, escapeProcessing, timeout, lineSeparator); 00160 cacheable = RequestType.CACHEABLE; 00161 isParsed = false; 00162 pkValue = null; 00163 } 00164 00173 public void parse(DatabaseSchema schema, int granularity, 00174 boolean isCaseSensitive) throws SQLException 00175 { 00176 if (granularity == ParsingGranularities.NO_PARSING) 00177 { 00178 cacheable = RequestType.CACHEABLE; 00179 isParsed = true; 00180 return; 00181 } 00182 00183 // Sanity check 00184 if (schema == null) 00185 throw new SQLException( 00186 "Unable to parse request with an undefined database schema"); 00187 00188 String originalSQL = this.trimCarriageReturn(); 00189 String sql = originalSQL.toLowerCase(); 00190 if (!isCaseSensitive) 00191 originalSQL = sql; 00192 00193 // Strip 'select' 00194 sql = sql.substring(6).trim(); 00195 00196 // Look for DISTINCT 00197 if (sql.startsWith("distinct")) 00198 sql = sql.substring(8).trim(); // Strip 'distinct ' 00199 00200 // Look for the begining of the FROM clause 00201 int fromIndex = sql.indexOf("from "); 00202 if (fromIndex == -1) 00203 throw new SQLException( 00204 "Unable to find the FROM keyword in this SELECT statement: '" + sql 00205 + "'"); 00206 00207 // Keep SELECT clause for later, we first have to check the 00208 // tables involved in the FROM clause 00209 int fshift = originalSQL.length() - sql.length(); 00210 String selectClause = (isCaseSensitive) ? originalSQL.substring(fshift, 00211 fshift + fromIndex) : sql.substring(0, fromIndex); 00212 00213 // Get rid of FROM 00214 sql = sql.substring(fromIndex + 5).trim(); 00215 00216 // Now find the boundaries of the FROM and WHERE clauses 00217 int whereIndex = 0; 00218 int parenthesis = 0; 00219 int lastParenthesisIdx = 0; 00220 boolean foundWhere = false; 00221 do 00222 { 00223 switch (sql.charAt(whereIndex)) 00224 { 00225 case '(' : 00226 parenthesis++; 00227 break; 00228 case ')' : 00229 parenthesis--; 00230 lastParenthesisIdx = whereIndex; 00231 break; 00232 case 'w' : 00233 if (parenthesis == 0) 00234 try 00235 { 00236 foundWhere = (sql.charAt(whereIndex + 1) == 'h') 00237 && (sql.charAt(whereIndex + 2) == 'e') 00238 && (sql.charAt(whereIndex + 3) == 'r') 00239 && (sql.charAt(whereIndex + 4) == 'e'); 00240 } 00241 catch (StringIndexOutOfBoundsException ignore) 00242 { 00243 foundWhere = false; 00244 } 00245 default : 00246 break; 00247 } 00248 whereIndex++; 00249 } 00250 while ((!foundWhere) && (whereIndex < sql.length())); 00251 if (foundWhere) 00252 whereIndex--; 00253 else 00254 whereIndex = -1; 00255 00256 // Warning! Here if whereIndex is -1 (no where clause) 00257 // endWhere is used to find the end of the FROM clause. 00258 // The variable name can be misleading but it's faster to do it this 00259 // way. 00260 int endWhere = sql.indexOf("group by ", lastParenthesisIdx); 00261 if (endWhere == -1) 00262 { 00263 endWhere = sql.indexOf("having ", lastParenthesisIdx); 00264 if (endWhere == -1) 00265 { 00266 endWhere = sql.indexOf("order by ", lastParenthesisIdx); 00267 if (endWhere == -1) 00268 { 00269 endWhere = sql.indexOf("limit ", lastParenthesisIdx); 00270 if (endWhere == -1) 00271 endWhere = sql.length(); 00272 } 00273 } 00274 } 00275 int endFrom; 00276 if (whereIndex == -1) 00277 endFrom = endWhere; 00278 else 00279 endFrom = whereIndex; 00280 00281 try 00282 { 00283 switch (granularity) 00284 { 00285 case ParsingGranularities.NO_PARSING : 00286 return; 00287 case ParsingGranularities.TABLE : 00288 int shift = originalSQL.length() - sql.length(); 00289 from = getFromTables(originalSQL.substring(shift, shift + endFrom) 00290 .trim(), schema, isCaseSensitive); 00291 break; 00292 case ParsingGranularities.COLUMN : 00293 case ParsingGranularities.COLUMN_UNIQUE : 00294 shift = originalSQL.length() - sql.length(); 00295 from = getFromTables(originalSQL.substring(shift, shift + endFrom) 00296 .trim(), schema, isCaseSensitive); 00297 // Find columns selected in the SELECT clause 00298 select = getSelectedColumns(selectClause, from, isCaseSensitive); 00299 if (whereIndex > 1) 00300 // Find columns involved in the WHERE clause (5="WHERE") 00301 where = getWhereColumns(originalSQL.substring( 00302 shift + whereIndex + 5, shift + endWhere).trim(), from, 00303 granularity == ParsingGranularities.COLUMN_UNIQUE, 00304 isCaseSensitive); 00305 break; 00306 default : 00307 throw new SQLException("Unsupported parsing granularity: '" 00308 + granularity + "'"); 00309 } 00310 } 00311 catch (SQLException e) 00312 { 00313 from = null; 00314 select = null; 00315 where = null; 00316 cacheable = RequestType.UNCACHEABLE; 00317 throw e; 00318 } 00319 00320 //Gokul added this 00321 //I need to have the aliases to determine if any of the OrderBy columns 00322 //are referenced using their alias 00323 00324 aliasFrom = from; 00325 00326 if (from != null) 00327 { 00328 // Convert 'from' to an ArrayList of String objects instead of 00329 // AliasedTables objects 00330 int size = from.size(); 00331 ArrayList unaliased = new ArrayList(size); 00332 for (int i = 0; i < size; i++) 00333 unaliased 00334 .add(((AliasedDatabaseTable) from.get(i)).getTable().getName()); 00335 from = unaliased; 00336 } 00337 00338 isParsed = true; 00339 } 00340 00344 public void cloneParsing(AbstractRequest request) 00345 { 00346 if (!request.isParsed()) 00347 return; 00348 SelectRequest selectRequest = (SelectRequest) request; 00349 select = selectRequest.getSelect(); 00350 from = selectRequest.getFrom(); 00351 where = selectRequest.getWhere(); 00352 cacheable = selectRequest.getCacheAbility(); 00353 pkValue = selectRequest.getPkValue(); 00354 isParsed = true; 00355 } 00356 00369 private ArrayList getFromTables(String fromClause, DatabaseSchema schema, 00370 boolean isCaseSensitive) throws SQLException 00371 { 00372 ArrayList result = new ArrayList(); 00373 00374 // Search for subselects in from clause 00375 try 00376 { 00377 int subSelect = fromClause.toLowerCase().indexOf("select"); 00378 while (subSelect != -1) 00379 { 00380 int subFromIndex = fromClause.indexOf("from", subSelect + 1) + 5; 00381 int bracket = subFromIndex; 00382 int parenthesis = 1; 00383 do 00384 { 00385 char c = fromClause.charAt(bracket); 00386 switch (c) 00387 { 00388 case '(' : 00389 parenthesis++; 00390 break; 00391 case ')' : 00392 parenthesis--; 00393 break; 00394 default : 00395 break; 00396 } 00397 bracket++; 00398 } 00399 while ((parenthesis > 0) && (bracket < fromClause.length())); 00400 00401 SelectRequest subQuery = new SelectRequest(fromClause.substring( 00402 subSelect, bracket - 1).trim(), this.escapeProcessing, 0, 00403 getLineSeparator()); 00404 subQuery.parse(schema, ParsingGranularities.TABLE, isCaseSensitive); 00405 for (Iterator iter = subQuery.getFrom().iterator(); iter.hasNext();) 00406 { 00407 result.add(new AliasedDatabaseTable(schema.getTable((String) iter 00408 .next(), isCaseSensitive), null)); 00409 } 00410 00411 if (subFromIndex + bracket > fromClause.length()) 00412 { 00413 if (subSelect > 0) 00414 { 00415 fromClause = fromClause.substring(0, subSelect - 1).trim(); 00416 if ((fromClause.length() > 0) 00417 && (fromClause.charAt(fromClause.length() - 1) == '(')) 00418 fromClause = fromClause.substring(0, fromClause.length() - 1) 00419 .trim(); 00420 } 00421 else 00422 fromClause = ""; 00423 break; // Nothing more to process 00424 } 00425 fromClause = (subSelect > 0 ? fromClause.substring(0, subSelect - 1) 00426 .trim() : "") 00427 + fromClause.substring(subFromIndex + bracket).trim(); 00428 subSelect = fromClause.toLowerCase().indexOf("select"); 00429 } 00430 } 00431 catch (RuntimeException e) 00432 { 00433 // Parsing failed, select everything 00434 return schema.getTables(); 00435 } 00436 00437 // Use a brutal force technique by matching schema table names in the from 00438 // clause 00439 ArrayList tables = schema.getTables(); 00440 int size = tables.size(); 00441 for (int i = 0; i < size; i++) 00442 { 00443 // Check if this table is found in the FROM string 00444 DatabaseTable t = (DatabaseTable) tables.get(i); 00445 String tableName = t.getName(); 00446 if (!isCaseSensitive) 00447 tableName = tableName.toLowerCase(); 00448 00449 // Check that we have a full match and not a partial match 00450 int index; 00451 int afterTableNameIndex = 0; 00452 boolean left; 00453 boolean right; 00454 do 00455 { 00456 index = fromClause.indexOf(tableName, afterTableNameIndex); 00457 if (index == -1) 00458 break; 00459 afterTableNameIndex = index + tableName.length(); 00460 left = (index == 0) 00461 || ((index > 0) && ((fromClause.charAt(index - 1) == ' ') 00462 || (fromClause.charAt(index - 1) == '(') 00463 || (fromClause.charAt(index - 1) == ',') || (fromClause 00464 .charAt(index - 1) == getLineSeparator().charAt( 00465 getLineSeparator().length() - 1)))); 00466 right = (afterTableNameIndex >= fromClause.length()) 00467 || ((afterTableNameIndex < fromClause.length()) && ((fromClause 00468 .charAt(afterTableNameIndex) == ' ') 00469 || (fromClause.charAt(afterTableNameIndex) == ',') 00470 || (fromClause.charAt(afterTableNameIndex) == ')') || (fromClause 00471 .charAt(afterTableNameIndex) == getLineSeparator().charAt(0)))); 00472 } 00473 while (!left || !right); 00474 if (index != -1) 00475 { 00476 // Check if the table has an alias 00477 // Example: SELECT x.price FROM item x 00478 String alias = null; 00479 index += tableName.length(); 00480 if ((index < fromClause.length()) && (fromClause.charAt(index) == ' ')) 00481 { 00482 char c; 00483 // Skip spaces before alias 00484 do 00485 { 00486 c = fromClause.charAt(index); 00487 index++; 00488 } 00489 while ((index < fromClause.length()) && (c != ' ') 00490 && (c != getLineSeparator().charAt(0))); 00491 if (index < fromClause.length()) 00492 { 00493 int start = index; 00494 do 00495 { 00496 c = fromClause.charAt(index); 00497 index++; 00498 } 00499 while ((index < fromClause.length()) && (c != ' ') && (c != ',') 00500 && (c != getLineSeparator().charAt(0))); 00501 alias = fromClause.substring(start, index - 1); 00502 } 00503 } 00504 result.add(new AliasedDatabaseTable(t, alias)); 00505 } 00506 } 00507 return result; 00508 } 00509 00524 private ArrayList getSelectedColumns(String selectClause, 00525 ArrayList aliasedFrom, boolean isCaseSensitive) 00526 { 00527 StringTokenizer selectTokens = new StringTokenizer(selectClause, ","); 00528 ArrayList result = new ArrayList(); 00529 StringBuffer unresolvedTokens = null; 00530 00531 while (selectTokens.hasMoreTokens()) 00532 { 00533 String token = selectTokens.nextToken().trim(); 00534 // Check if it is a function, e.g., MAX, COUNT, etc. 00535 if (isSqlFunction(token)) 00536 { 00537 // token has the following form: 00538 // max(...) 00539 // or 00540 // count(...) 00541 int leftPar = token.indexOf("("); 00542 token = token.substring(leftPar + 1, token.length() - 1); 00543 } 00544 // Is it using an aliased table name (x.price for example) ? 00545 String alias = null; 00546 int aliasIdx = token.indexOf("."); 00547 if (aliasIdx != -1) 00548 { 00549 alias = token.substring(0, aliasIdx); 00550 token = token.substring(aliasIdx + 1); // Get 00551 // rid 00552 // of 00553 // the 00554 // '.' 00555 } 00556 00557 // Discard any AS clause 00558 int as = token.indexOf(" as "); 00559 if (as != -1) 00560 token = token.substring(0, as).trim(); 00561 00562 // Now token only contains the column name 00563 00564 // Deal with SELECT * or x.* 00565 if (token.indexOf("*") != -1) 00566 { 00567 if (alias == null) 00568 { 00569 // We have to take all colums of all tables of the FROM 00570 // clause 00571 int size = aliasedFrom.size(); 00572 for (int i = 0; i < size; i++) 00573 { 00574 DatabaseTable t = ((AliasedDatabaseTable) aliasedFrom.get(i)) 00575 .getTable(); 00576 ArrayList cols = t.getColumns(); 00577 int colSize = cols.size(); 00578 for (int j = 0; j < colSize; j++) 00579 result.add(new TableColumn(t.getName(), ((DatabaseColumn) cols 00580 .get(j)).getName())); 00581 } 00582 return result; 00583 } 00584 else 00585 { 00586 // Add all colums of the table corresponding to the alias 00587 int size = aliasedFrom.size(); 00588 for (int i = 0; i < size; i++) 00589 { 00590 AliasedDatabaseTable adt = (AliasedDatabaseTable) aliasedFrom 00591 .get(i); 00592 // The alias could be the full name of the table 00593 // instead of a "real" alias 00594 if (alias.equals(adt.getAlias()) 00595 || alias.equals(adt.getTable().getName())) 00596 { 00597 DatabaseTable t = adt.getTable(); 00598 ArrayList cols = t.getColumns(); 00599 int colSize = cols.size(); 00600 for (int j = 0; j < colSize; j++) 00601 result.add(new TableColumn(t.getName(), ((DatabaseColumn) cols 00602 .get(i)).getName())); 00603 break; 00604 } 00605 } 00606 } 00607 continue; 00608 } 00609 00610 // First, we suppose that it's a simple column name. 00611 // If it fails, we will consider it later. 00612 DatabaseColumn col = null; 00613 00614 if (alias == null) 00615 { 00616 int size = aliasedFrom.size(); 00617 for (int i = 0; i < size; i++) 00618 { 00619 DatabaseTable t = ((AliasedDatabaseTable) aliasedFrom.get(i)) 00620 .getTable(); 00621 col = t.getColumn(token, isCaseSensitive); 00622 if (col != null) 00623 { 00624 result.add(new TableColumn(t.getName(), col.getName())); 00625 break; 00626 } 00627 } 00628 } 00629 else 00630 // same with an alias 00631 { 00632 int size = aliasedFrom.size(); 00633 for (int i = 0; i < size; i++) 00634 { 00635 AliasedDatabaseTable t = (AliasedDatabaseTable) aliasedFrom.get(i); 00636 // It can be either an alias or the fully qualified name of 00637 // the table 00638 if (alias.equals(t.getAlias()) 00639 || alias.equals(t.getTable().getName())) 00640 { 00641 col = t.getTable().getColumn(token, isCaseSensitive); 00642 if (col != null) 00643 { 00644 result 00645 .add(new TableColumn(t.getTable().getName(), col.getName())); 00646 break; 00647 } 00648 } 00649 } 00650 } 00651 00652 if (col == null) 00653 { 00654 if (unresolvedTokens == null) 00655 unresolvedTokens = new StringBuffer(); 00656 unresolvedTokens.append(token); 00657 unresolvedTokens.append(" "); 00658 } 00659 } 00660 00661 if (unresolvedTokens != null) 00662 { 00663 // Those tokens may be complex expressions, so instead of parsing 00664 // them, we use a brutal force technique and we try to directly 00665 // identify every column name of each table. 00666 DatabaseColumn col; 00667 00668 String unresolvedTokensString = unresolvedTokens.toString(); 00669 if (!isCaseSensitive) 00670 unresolvedTokensString = unresolvedTokensString.toLowerCase(); 00671 00672 int asize = aliasedFrom.size(); 00673 for (int i = 0; i < asize; i++) 00674 { 00675 DatabaseTable t = ((AliasedDatabaseTable) aliasedFrom.get(i)) 00676 .getTable(); 00677 ArrayList cols = t.getColumns(); 00678 int size = cols.size(); 00679 for (int j = 0; j < size; j++) 00680 { 00681 col = (DatabaseColumn) cols.get(j); 00682 String columnName = col.getName(); 00683 if (!isCaseSensitive) 00684 columnName = columnName.toLowerCase(); 00685 00686 // if pattern found and column not already in result, it's a 00687 // dependency ! 00688 int matchIdx = unresolvedTokensString.indexOf(columnName); 00689 if (matchIdx != -1) 00690 if ((matchIdx == 0) 00691 || (unresolvedTokens.charAt(matchIdx - 1) == ' ') 00692 || (unresolvedTokens.charAt(matchIdx - 1) == '(') 00693 || (unresolvedTokens.charAt(matchIdx - 1) == '.')) 00694 { 00695 TableColumn c = new TableColumn(t.getName(), col.getName()); 00696 if (!result.contains(c)) 00697 result.add(c); 00698 } 00699 } 00700 } 00701 } 00702 return result; 00703 } 00704 00713 private boolean isSqlFunction(String str) 00714 { 00715 00716 if (str != null) 00717 { 00718 if (str.startsWith("max(") && str.endsWith(")")) 00719 { 00720 funcType = SelectRequest.MAX_FUNCTION; 00721 return true; 00722 } 00723 else if (str.startsWith("count(") && str.endsWith(")")) 00724 { 00725 funcType = SelectRequest.COUNT_FUNCTION; 00726 return true; 00727 } 00728 else if (str.startsWith("avg(") && str.endsWith(")")) 00729 { 00730 funcType = SelectRequest.AVERAGE_FUNCTION; 00731 return true; 00732 } 00733 else if (str.startsWith("min(") && str.endsWith(")")) 00734 { 00735 funcType = SelectRequest.MIN_FUNCTION; 00736 return true; 00737 } 00738 else if (str.startsWith("sum(") && str.endsWith(")")) 00739 { 00740 funcType = SelectRequest.SUM_FUNCTION; 00741 return true; 00742 } 00743 else 00744 { 00745 funcType = SelectRequest.NO_FUNCTION; 00746 return false; 00747 } 00748 } 00749 else 00750 return false; 00751 } 00752 00769 private ArrayList getWhereColumns(String whereClause, ArrayList aliasedFrom, 00770 boolean setUniqueCacheable, boolean isCaseSensitive) 00771 { 00772 ArrayList result = new ArrayList(); // TableColumn 00773 // objects 00774 00775 if (!isCaseSensitive) 00776 whereClause = whereClause.toLowerCase(); 00777 00778 // Instead of parsing the clause, we use a brutal force technique 00779 // and we try to directly identify every column name of each table. 00780 DatabaseColumn col; 00781 for (int i = 0; i < aliasedFrom.size(); i++) 00782 { 00783 DatabaseTable t = ((AliasedDatabaseTable) aliasedFrom.get(i)).getTable(); 00784 ArrayList cols = t.getColumns(); 00785 int size = cols.size(); 00786 for (int j = 0; j < size; j++) 00787 { 00788 col = (DatabaseColumn) cols.get(j); 00789 // if pattern found and column not already in result, it's a 00790 // dependency ! 00791 String columnName = col.getName(); 00792 if (!isCaseSensitive) 00793 columnName = columnName.toLowerCase(); 00794 00795 int matchIdx = whereClause.indexOf(columnName); 00796 while (matchIdx > 0) 00797 { 00798 // Try to check that we got the full pattern and not a 00799 // sub-pattern 00800 char beforePattern = whereClause.charAt(matchIdx - 1); 00801 if (((beforePattern >= 'a') && (beforePattern <= 'z')) 00802 || ((beforePattern >= 'A') && (beforePattern <= 'Z')) 00803 || (beforePattern == '_')) 00804 matchIdx = whereClause.indexOf(columnName, matchIdx + 1); 00805 else 00806 { 00807 char afterPattern; 00808 try 00809 { 00810 afterPattern = whereClause.charAt(matchIdx + columnName.length()); 00811 if (((afterPattern >= 'a') && (afterPattern <= 'z')) 00812 || ((afterPattern >= 'A') && (afterPattern <= 'Z')) 00813 || (afterPattern == '_')) 00814 { 00815 // This is a subset of the full name of another 00816 // column, 00817 //let's jump to next mathing pattern 00818 matchIdx = whereClause.indexOf(columnName, matchIdx + 1); 00819 } 00820 else 00821 break; 00822 } 00823 catch (IndexOutOfBoundsException e) 00824 { 00825 break; 00826 } 00827 } 00828 } 00829 if (matchIdx == -1) 00830 continue; 00831 result.add(new TableColumn(t.getName(), col.getName())); 00832 00833 if (setUniqueCacheable) 00834 { // Check if this request selects a 00835 // unique row 00836 if (!col.isUnique()) 00837 { // Column has no unicity constraint, 00838 // we can select multiple rows 00839 // with same value, give up. 00840 setUniqueCacheable = false; 00841 continue; 00842 } 00843 00844 // Check if the column is in the left side of an equality 00845 // with a 00846 // constant. 00847 // e.g.: 'column_name1 = 10' is ok 00848 // but '5=table_name.column_name2' will fail 00849 00850 int lookingForEqual = matchIdx + columnName.length(); 00851 boolean searchReverse = false; 00852 try 00853 { 00854 while (whereClause.charAt(lookingForEqual) == ' ') 00855 lookingForEqual++; 00856 } 00857 catch (Exception e) 00858 { 00859 searchReverse = true; 00860 } 00861 00862 String rightSide; 00863 00864 if (searchReverse || (whereClause.charAt(lookingForEqual) != '=')) 00865 { 00866 try 00867 { 00868 // try reverse 00869 StringBuffer sb = new StringBuffer(whereClause.substring(0, 00870 lookingForEqual)); 00871 String reverse = sb.reverse().toString(); 00872 reverse = reverse.substring(reverse.indexOf('=') + 1); 00873 sb = new StringBuffer(reverse); 00874 // Get back the original values 00875 sb = sb.reverse(); 00876 rightSide = sb.toString(); 00877 } 00878 catch (Exception e) 00879 { 00880 // No equality, it is not unique cacheable 00881 setUniqueCacheable = false; 00882 continue; 00883 } 00884 } 00885 else 00886 { 00887 // We found it let's move to next char 00888 int nextSpace = lookingForEqual + 1; 00889 try 00890 { 00891 while (whereClause.charAt(nextSpace) == ' ') 00892 nextSpace++; 00893 } 00894 catch (Exception e1) 00895 { // This should not happen 00896 // unless we get a query like: 00897 // 'select ... where id= ' 00898 setUniqueCacheable = false; 00899 continue; 00900 } 00901 00902 rightSide = whereClause.substring(nextSpace); 00903 } 00904 char firstChar = rightSide.charAt(0); 00905 if ((firstChar == '\'') || (firstChar == '"') 00906 || ((firstChar >= '0') && (firstChar <= '9')) 00907 || (firstChar == '?')) 00908 { // Ok, the value is either 00909 // '...' or "..." or starts 00910 // with a 00911 // number which is enough for us to consider that it is 00912 // an 00913 // acceptable constant. 00914 pkValue = rightSide; 00915 } 00916 else 00917 { 00918 setUniqueCacheable = false; 00919 continue; 00920 } 00921 } 00922 } 00923 } 00924 00925 if (setUniqueCacheable && !result.isEmpty()) 00926 cacheable = RequestType.UNIQUE_CACHEABLE; 00927 00928 return result; 00929 } 00930 00938 public ArrayList getSelect() 00939 { 00940 return select; 00941 } 00942 00950 public ArrayList getFrom() 00951 { 00952 return from; 00953 } 00954 00962 public ArrayList getAliasedFrom() 00963 { 00964 return aliasFrom; 00965 } 00966 00974 public ArrayList getWhere() 00975 { 00976 return where; 00977 } 00978 00986 public ArrayList getOrderBy() 00987 { 00988 return order; 00989 } 00990 00998 public Hashtable getWhereValues() 00999 { 01000 return whereValues; 01001 } 01002 01007 public boolean isReadRequest() 01008 { 01009 return true; 01010 } 01011 01016 public boolean isWriteRequest() 01017 { 01018 return false; 01019 } 01020 01025 public boolean isUnknownRequest() 01026 { 01027 return false; 01028 } 01029 01033 public String getPkValue() 01034 { 01035 return pkValue; 01036 } 01037 01041 public void setPkValue(String pkValue) 01042 { 01043 this.pkValue = pkValue; 01044 } 01045 01051 public String getCursorName() 01052 { 01053 return cursorName; 01054 } 01055 01061 public void setCursorName(String cursorName) 01062 { 01063 this.cursorName = cursorName; 01064 } 01065 01069 public void debug() 01070 { 01071 super.debug(); 01072 if (select != null) 01073 { 01074 System.out.println("Selected columns:"); 01075 for (int i = 0; i < select.size(); i++) 01076 System.out 01077 .println(" " + ((TableColumn) select.get(i)).getColumnName()); 01078 } 01079 else 01080 System.out.println("No information on selected columns"); 01081 01082 if (select != null) 01083 { 01084 System.out.println(""); 01085 System.out.println("From tables:"); 01086 for (int i = 0; i < from.size(); i++) 01087 System.out.println(" " + from.get(i)); 01088 } 01089 else 01090 System.out.println("No information on from tables"); 01091 01092 System.out.println(""); 01093 System.out.println("Where columns:"); 01094 if (where == null) 01095 System.out.println(" No Where clause"); 01096 else 01097 for (int i = 0; i < where.size(); i++) 01098 System.out.print(" " + ((TableColumn) where.get(i)).getColumnName()); 01099 01100 System.out.println(""); 01101 System.out.println("PK value: " + pkValue); 01102 } 01103 01104 }

CJDBCversion1.0.4に対してTue Oct 12 15:15:58 2004に生成されました。 doxygen 1.3.8