Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

SQLtoLDAPQueryTranslator.cpp

00001                               /* SQLtoLDAPQueryTranslator.cpp */
00002 
00003 /*
00004  *  Implementation of SQLtoLDAPQueryTranslator.h
00005  */
00006 #include "SQLtoLDAPQueryTranslator.h"
00007 
00008 using namespace LcgInfo;
00009 using namespace std;
00010 
00011 /******************  METHODS FOR CLASS SQLtoLDAPQueryTranslator  ********************/
00012 
00013 const std::string SQLtoLDAPQueryTranslator::CHARS_TO_DIVIDE_LDAP_WORDS=" \t=><()!";
00014 
00015 SQLtoLDAPQueryTranslator::SQLtoLDAPQueryTranslator()
00016 : SQLQueryTranslator(){
00017 }
00018 
00019 SQLtoLDAPQueryTranslator::SQLtoLDAPQueryTranslator(string const & pMapFile)
00020 : SQLQueryTranslator(pMapFile){
00021 }
00022 
00023 SQLtoLDAPQueryTranslator::SQLtoLDAPQueryTranslator(LcgConfigBuffer::ConfigBuffer & pMap)
00024 : SQLQueryTranslator(pMap){
00025 }
00026 
00027 SQLtoLDAPQueryTranslator::~SQLtoLDAPQueryTranslator(){
00028 }
00029 
00030 vector<string> SQLtoLDAPQueryTranslator::translateQuery(string const & pQueryCanonical){
00031    // Define the necessary variables
00032    SQLPredicateTree * pred=new SQLtoLDAPPredicateTree();
00033    vector<string> rows;
00034    set<string> tables;
00035    string translated;
00036    vector<string> result;
00037    vector<string> newResults;
00038 
00039    // Let our parent's translateSemantic() method do the job
00040    translateSemantic(pQueryCanonical, *pred, rows, tables);
00041 
00042    // Build the subqueries and the predicate of the last query to return
00043    result.clear();
00044    if(!pred->empty())
00045       translated = pred->evaluate(result);  //where clause (may throw QueryTranslationException)
00046 
00047    //Now, add the rows to return to the query that corresponds to it
00048    vector<string> tokens;
00049    vector<short int> indices;
00050    string subqueryTable, askedTable, attrib, listOfResults;
00051    string::size_type pos, queryNum;
00052    bool included=false;
00053    for(vector<string>::iterator i=rows.begin(); i!=rows.end(); i++){
00054       askedTable=extractTable(*i);   //table of the current element in the row list
00055       included=false;
00056       queryNum=result.size()-1;
00057       for(vector<string>::reverse_iterator j=result.rbegin(); j!=result.rend(); j++, queryNum--){
00058          tokenizeStrWithIndices(*j, tokens, indices);
00059          subqueryTable=extractTable(tokens.back()); //table of the table.row asked in subquery
00060          if(i==rows.begin()){  //first time
00061             //copy the line (without the table names or =... parts)            
00062             attrib=extractRow(tokens.back());            
00063             pos=attrib.find_last_of('=',attrib.size()-1);
00064             if(pos!=string::npos) attrib=attrib.substr(0,pos);
00065             pos = indices.back();
00066             string aux=(*j).substr(0,pos) + attrib;
00067             newResults.insert(newResults.begin(), aux); 
00068             //add the objectclass filter 
00069             if(pos>0){//if there was already something
00070                newResults.front().insert(pos-1, ")");
00071                newResults.front().insert(0, "(&(objectclass=" + subqueryTable + ")"); 
00072             }
00073             else{//if there was nothing
00074                newResults.front().insert(0, "(objectclass=" + subqueryTable + ") "); 
00075             }
00076          }
00077          if(askedTable==subqueryTable){  //asking the same table ==> add the row, if...
00078             if(tokens.back()!=(*i)){  //...if the asked attribute is not already there
00079                listOfResults+=int2str(queryNum)+"-1,";
00080                attrib=extractRow(*i);            
00081                pos=attrib.find_last_of('=',attrib.size()-1);
00082                if(pos!=string::npos) attrib=attrib.substr(0,pos);
00083                if(newResults.size()>queryNum)
00084                   newResults.at(queryNum) +=  " " + attrib;
00085                else
00086                   newResults.back() += " " + attrib;
00087             }
00088             else{                        //otherwise, warn that the attr has to be returned 
00089                listOfResults+=int2str(queryNum)+"-0,";
00090             }
00091             included=true;
00092          }
00093       }
00094       if(!included){     //if not in a subquery, add to the last
00095          //but first, eliminate trailing =xxxx
00096          attrib=extractRow(*i);            
00097          pos=attrib.find_last_of('=',attrib.size()-1);
00098          if(pos!=string::npos) attrib=attrib.substr(0,pos);
00099          //and add the objectclass filter (only once)
00100          if(i==rows.begin()){
00101             listOfResults+=int2str(result.size())+"-0,";
00102             subqueryTable=extractTable(*i);   //table of the table.row asked in subquery
00103             if(translated.size()>0){//if there was something already
00104                translated.insert(translated.size(), ")");
00105                translated.insert(0, "(&(objectclass=" + subqueryTable + ")");
00106             }
00107             else{
00108                listOfResults+=int2str(result.size())+"-1,";
00109                translated.insert(0, "(objectclass=" + subqueryTable + ")");
00110             }
00111          }
00112          //now add the row to return 
00113          translated += " " + attrib;
00114       }  
00115    }
00116    newResults.push_back(translated);
00117 
00118    //Last element, the list of rows to return
00119    newResults.push_back(listOfResults);
00120 
00121    delete pred;  
00122    return newResults;
00123    
00124 }//end of translateQuery()

Generated on Tue Oct 5 14:42:45 2004 for LCG Information System Interface by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002