📄 tinysqlwhere.java
字号:
/*
* tinySQLWhere - Class to handle all Where clause processing.
*
* $Author: davis $
* $Date: 2004/12/18 21:24:13 $
* $Revision: 1.1 $
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Revision History:
*
* Written by Davis Swan in May, 2004.
*/
package com.sqlmagic.tinysql;
import java.util.*;
import java.lang.*;
import java.io.*;
import java.sql.SQLException;
import java.sql.Types;
public class tinySQLWhere
{
Vector whereClauseList;
/*
* The constructor builds a Where clause object from the input string.
*/
public tinySQLWhere(String whereString,Hashtable tableDefs)
throws tinySQLException
{
FieldTokenizer ft;
Vector whereConditions;
tsColumn leftColumn,rightColumn;
Object whereObj;
StringBuffer fieldBuffer;
String nextField,upperField,wherePhrase,comp,left,right,andOr,lastWord;
Vector whereCondition;
String[] comparisons = {"<=","=<",">=","=>","=","<>","!=",">","<",
"LIKE","NOT LIKE","IS"};
String[] fields,keepFields;
boolean inBrackets=false,foundFunction=false;
int i,j,foundKeyWord,foundComp,startAt,foundAnd,foundOr,keepCount;
/*
* The whereClauseList is a Vector containing pointers to whereCondition
* Vectors or tinySQLWhere objects.
*/
whereConditions = new Vector();
whereClauseList = new Vector();
/*
* Identify any phrases that are contained within brackets. Note that
* the FieldTokenizer will catch function definitions as well as
* subPhrases so there has to be additional logic to reconstruct
* the functions.
*/
ft = new FieldTokenizer(whereString,'(',true);
fields = ft.getFields();
keepFields = new String[fields.length];
lastWord = "NULL";
fieldBuffer = new StringBuffer();
foundFunction = false;
keepCount = 0;
for ( i = 0; i < fields.length; i++ )
{
keepFields[i] = "";
if ( fields[i].equals("(") )
{
/*
* If this is a known function reconstruct the function definition
* and save the entire string.
*/
foundFunction = Utils.isFunctionName(lastWord);
if ( foundFunction )
{
fieldBuffer.append("(");
} else {
if ( fieldBuffer.length() > 0 )
{
keepFields[keepCount] = fieldBuffer.toString();
keepCount++;
fieldBuffer.delete(0,fieldBuffer.length());
}
keepFields[keepCount] = "(";
keepCount++;
}
} else if ( fields[i].equals(")") ) {
if ( foundFunction )
{
fieldBuffer.append(") ");
foundFunction = false;
} else {
if ( fieldBuffer.length() > 0 )
{
keepFields[keepCount] = fieldBuffer.toString();
keepCount++;
fieldBuffer.delete(0,fieldBuffer.length());
}
keepFields[keepCount] = ")";
keepCount++;
}
} else {
fieldBuffer.append(fields[i]);
}
lastWord = fields[i].substring(fields[i].lastIndexOf(" ") + 1);
}
/*
* Keep last subPhrase
*/
if ( fieldBuffer.length() > 0 )
{
keepFields[keepCount] = fieldBuffer.toString();
keepCount++;
}
for ( i = 0; i < keepCount; i++ )
{
if ( tinySQLGlobals.WHERE_DEBUG )
System.out.println("keepFields[" + i + "]=" + keepFields[i]);
nextField = keepFields[i];
upperField = nextField.toUpperCase();
if ( nextField.equals("(") )
{
whereObj = (Object)null;
inBrackets = true;
} else if ( nextField.equals(")") ) {
inBrackets = false;
whereObj = (Object)null;
} else if ( inBrackets ) {
whereObj = new tinySQLWhere(nextField,tableDefs);
whereConditions.addElement(whereObj);
} else {
/*
* Look for AND/OR keywords - if none are found process the
* entire string.
*/
andOr = "AND";
startAt = 0;
while ( startAt < upperField.length() )
{
if ( upperField.startsWith("AND ") )
{
foundAnd = 0;
} else {
foundAnd = upperField.indexOf(" AND",startAt);
/*
* Make sure this is not just part of a longer string.
*/
if ( foundAnd > -1 & foundAnd < upperField.length() - 4 )
if ( upperField.charAt(foundAnd + 4) != ' ' )
foundAnd = -1;
}
if ( upperField.startsWith("OR " ) )
{
foundOr = 0;
} else {
foundOr = upperField.indexOf(" OR",startAt);
if ( foundOr > -1 & foundOr < upperField.length() - 3 )
if ( upperField.charAt(foundOr + 3) != ' ' )
foundOr = -1;
}
foundKeyWord = upperField.length();
if ( foundAnd > -1 ) foundKeyWord = foundAnd;
if ( foundOr > -1 & foundOr < foundKeyWord )
{
foundKeyWord = foundOr;
andOr = "OR";
}
if ( foundKeyWord == 0 )
{
startAt = andOr.length() + 1;
foundKeyWord = upperField.length();
}
wherePhrase = nextField.substring(startAt,foundKeyWord);
if ( tinySQLGlobals.WHERE_DEBUG )
System.out.println("Where phrase is " + wherePhrase);
if ( foundKeyWord < upperField.length() - 4 )
andOr = upperField.substring(foundKeyWord+1,foundKeyWord+3);
/*
* Build a whereCondition Vector. The elements are
* as follows:
* 0 - left column object
* 1 - comparison
* 2 - right column object
* 3 - status
*
* The status values indicate which parts of the where
* condition have been set.
*/
whereCondition = new Vector();
for ( j = 0; j < comparisons.length; j++ )
{
comp = comparisons[j];
foundComp = wherePhrase.toUpperCase().indexOf(comp);
if ( foundComp > -1 )
{
left = wherePhrase.substring(0,foundComp).trim();
leftColumn = new tsColumn(left,tableDefs,"WHERE");
whereCondition.addElement(leftColumn);
whereCondition.addElement(comp);
right = wherePhrase.substring(foundComp + comp.length()).trim();
if ( comp.equals("IS") )
right = "'" + right.toUpperCase() + "'";
rightColumn = new tsColumn(right,tableDefs,"WHERE");
whereCondition.addElement(rightColumn);
if ( leftColumn.isConstant & rightColumn.isConstant )
whereCondition.addElement("BOTH");
else if ( leftColumn.isConstant )
whereCondition.addElement("LEFT");
else if ( rightColumn.isConstant )
whereCondition.addElement("RIGHT");
else
whereCondition.addElement("UNKNOWN");
break;
}
}
whereConditions.addElement(whereCondition);
/*
* If this condition and the previous one are joined by an
* AND keyword, add the condition to the existing Vector.
* For an OR keyword, create a new entry in the whereClauseList.
*/
if ( andOr.equals("OR") )
{
whereClauseList.addElement(whereConditions);
whereConditions = new Vector();
}
startAt = foundKeyWord + andOr.length() + 2;
}
}
}
/*
* Add the last where condition to the list.
*/
if ( whereConditions.size() > 0 )
whereClauseList.addElement(whereConditions);
if ( tinySQLGlobals.WHERE_DEBUG )
System.out.println("Where clause is \n" + toString());
}
/*
* This method returns the column to build an index on. This is very
* primitive and only works on a single column that is compared to
* to a constant.
*/
public Vector getIndexCondition(String inputTableName)
{
int i,j;
Vector whereConditions;
tsColumn leftColumn,rightColumn;
Object whereObj;
String objectType,columnName,tableName,comparison;
Vector whereCondition;
StringBuffer outputBuffer = new StringBuffer();
for ( i = 0 ; i < whereClauseList.size(); i++ )
{
whereConditions = (Vector)whereClauseList.elementAt(i);
for ( j = 0; j < whereConditions.size(); j++ )
{
/*
* Where conditions can be tinySQLWhere objects or String arrays.
*/
whereObj = whereConditions.elementAt(j);
objectType = whereObj.getClass().getName();
if ( objectType.endsWith("java.util.Vector") )
{
whereCondition = (Vector)whereObj;
leftColumn = (tsColumn)whereCondition.elementAt(0);
comparison = (String)whereCondition.elementAt(1);
rightColumn = (tsColumn)whereCondition.elementAt(2);
if ( leftColumn.tableName.equals(inputTableName) &
rightColumn.isConstant & comparison.equals("=") )
{
return whereCondition;
} else if ( leftColumn.tableName.equals(inputTableName) &
rightColumn.isConstant & comparison.equals("=") ) {
return whereCondition;
}
}
}
}
return (Vector)null;
}
/*
* Clear all the non-constant values in all where conditions
*/
public void clearValues(String inputTableName)
{
int i,j;
Vector whereConditions;
tsColumn leftColumn,rightColumn;
Object whereObj;
String objectType,columnName,tableName,status;
Vector whereCondition;
StringBuffer outputBuffer = new StringBuffer();
for ( i = 0 ; i < whereClauseList.size(); i++ )
{
whereConditions = (Vector)whereClauseList.elementAt(i);
for ( j = 0; j < whereConditions.size(); j++ )
{
/*
* Where conditions can be tinySQLWhere objects or String arrays.
*/
whereObj = whereConditions.elementAt(j);
objectType = whereObj.getClass().getName();
if ( objectType.endsWith("tinySQLWhere") )
{
((tinySQLWhere)whereObj).clearValues(inputTableName);
} else if ( objectType.endsWith("java.util.Vector") ) {
whereCondition = (Vector)whereObj;
status = (String)whereCondition.elementAt(3);
if ( status.equals("UNKNOWN") ) continue;
/*
* Check left side of condition
*/
leftColumn = (tsColumn)whereCondition.elementAt(0);
if ( leftColumn.clear(inputTableName) )
{
if ( status.equals("LEFT") )
whereCondition.setElementAt("UNKNOWN",3);
else
whereCondition.setElementAt("RIGHT",3);
}
/*
* Check right side of condition
*/
rightColumn = (tsColumn)whereCondition.elementAt(2);
if ( rightColumn.clear(inputTableName) )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -