00001
00002
00003
00004
00005
00006 #include "SQLtoLDAPPredicateTree.h"
00007
00008 using namespace LcgInfo;
00009 using namespace std;
00010
00011
00012
00013
00014 SQLtoLDAPPredicateTree::SQLtoLDAPPredicateTree()
00015 :SQLPredicateTree(){
00016 }
00017
00018 SQLtoLDAPPredicateTree::~SQLtoLDAPPredicateTree(){
00019 }
00020
00021 SQLtoLDAPPredicateTree* SQLtoLDAPPredicateTree::create(){
00022 return new SQLtoLDAPPredicateTree();
00023 }
00024
00025 SQLtoLDAPPredicateTree * SQLtoLDAPPredicateTree::clone(){
00026 SQLtoLDAPPredicateTree * aux=create();
00027
00028
00029 aux->setValue(value());
00030 aux->setType(type());
00031 aux->setDepth(depth());
00032
00033
00034 if(left()!=NULL)
00035 aux->setLeft(left()->clone());
00036 else
00037 aux->setLeft(NULL);
00038 if(right()!=NULL)
00039 aux->setRight(right()->clone());
00040 else
00041 aux->setRight(NULL);
00042
00043 return aux;
00044 }
00045
00046 string SQLtoLDAPPredicateTree::evaluate(vector<string> & pQueries){
00047 if(depth()==0) pQueries.clear();
00048 string aux;
00049 switch (this->type()){
00050 case COMPARISON:
00051
00052 if((this->value()=="=") || (this->value()==">=") || (this->value()=="<=")){
00053 aux='(' + left()->evaluate(pQueries) ;
00054 aux+= this->value() + right()->evaluate(pQueries) + ')';
00055 }
00056 if(this->value()==">"){
00057 aux="(! (" + left()->evaluate(pQueries) + "<=";
00058 aux+= right()->evaluate(pQueries) + "))";
00059 }
00060 if(this->value()=="<"){
00061 aux="(! (" + left()->evaluate(pQueries) + ">=";
00062 aux+= right()->evaluate(pQueries) + "))";
00063 }
00064 if(this->value()=="<>"){
00065 aux="(! (" + left()->evaluate(pQueries) + "=";
00066 aux+= right()->evaluate(pQueries) + "))";
00067 }
00068 if(nocaseCompare(this->value(),"LIKE")) {
00069
00070 string temp=right()->evaluate(pQueries);
00071 string::size_type pos = temp.find_first_of("%", 0);
00072 while (pos != string::npos){
00073 int count=0;
00074 for(int i=pos-1; temp.at(i)=='\\'; i--, count++);
00075 if(count>0){
00076 temp.erase(pos-count/2,count/2);
00077 pos-=count/2;
00078 if(count%2==0)
00079 temp.replace(pos,1,"*");
00080 else
00081 temp.erase(pos-1,1);
00082 }
00083 else temp.replace(pos,1,"*");
00084
00085 pos = temp.find_first_of("%", pos+1);
00086 }
00087 aux='(' + left()->evaluate(pQueries) + " = " + temp + ')';
00088 }
00089 break;
00090
00091 case BOOLEAN:
00092 if (nocaseCompare(this->value(),"NOT")){
00093 if(right()->relatesTables())
00094 aux="(! " + substituteSubquery(right(), 0, pQueries) + ')';
00095 else
00096 aux="(! " + right()->evaluate(pQueries) + ')';
00097 }
00098
00099 else if (nocaseCompare(this->value(),"AND")){
00100
00101 if((right()==0)&&(left()==0)) return "";
00102 if(right()==0) aux = left()->evaluate(pQueries);
00103 else if(left()==0){ aux = right()->evaluate(pQueries);}
00104
00105
00106 else if((left()->relatesTables())&&(!(right()->relatesTables()))){
00107 aux=substituteSubquery(left(), right(), pQueries);
00108 }
00109 else if((right()->relatesTables())&&(!(left()->relatesTables()))){
00110 aux=substituteSubquery(right(), left(), pQueries);
00111 }
00112 else if((right()->relatesTables())&&(left()->relatesTables())){
00113 aux = "(& " + substituteSubquery(left(), 0, pQueries);
00114 aux += substituteSubquery(right(), 0, pQueries) + ')';
00115 }
00116 else{
00117 aux="(& " + left()->evaluate(pQueries);
00118 aux+=right()->evaluate(pQueries) + ')';
00119 }
00120 }
00121
00122 else if (nocaseCompare(this->value(),"OR")){
00123
00124 if((right()==0) || (left()==0)) return "";
00125
00126 aux="(| " + left()->evaluate(pQueries) + right()->evaluate(pQueries) + ')';
00127 }
00128 break;
00129
00130 case LEAF:
00131
00132 string::size_type pos=0;
00133 if((!isLiteral(value())) && (!isNumber(value()))){
00134 pos=value().find_last_of('.', value().size()-1);
00135 if(pos!=string::npos)
00136 aux=value().substr(pos+1);
00137 else
00138 aux=value();
00139 }
00140
00141
00142 if(isLiteral(value()))
00143 aux=value().substr(1,value().size()-2);
00144
00145
00146 if(depth()!=-1){
00147 string::size_type pos=aux.find('#',0);
00148 while (pos != string::npos){
00149 aux.insert(pos,"\\");
00150 pos=aux.find('#',pos+2);
00151 }
00152 }
00153 }
00154
00155 if(aux.empty()){
00156 string msg="Parsing error. The node could not be evaluated.";
00157 msg += "\nThis node's value: " + value() + "\nThis node's depth: " + int2str(depth());
00158 throw QueryTranslationException(msg,__FILE__,__LINE__);
00159 }
00160
00161 return aux;
00162 };
00163
00164
00165 string SQLtoLDAPPredicateTree::substituteSubquery(PredicateTree * pNode,
00166 PredicateTree * pTheOther, vector<string> & pQueries){
00167
00168 string temp, result, subquery;
00169 string tempType;
00170 int tempDepth;
00171
00172 if(pTheOther!=0){
00173 subquery=pTheOther->evaluate(pQueries) + " ";
00174
00175 subquery+= pNode->right()->value();
00176 }
00177 else
00178 subquery=pNode->right()->evaluate(pQueries);
00179 pQueries.push_back(subquery);
00180
00181 temp=pNode->right()->value();
00182 tempDepth=pNode->right()->depth();
00183
00184 pNode->right()->setValue("\'#" + int2str(pQueries.size()-1) + "#\'");
00185 pNode->right()->setDepth(-1);
00186 result=pNode->evaluate(pQueries);
00187 pNode->right()->setValue(temp);
00188 pNode->right()->setDepth(tempDepth);
00189
00190 return result;
00191 }