Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DbiAsciiTablePreparer.cxx

Go to the documentation of this file.
00001 // $Id: DbiAsciiTablePreparer.cxx,v 1.4 2007/04/26 14:19:57 west Exp $
00002 
00004 //
00005 // DbiAsciiTablePreparer
00006 //
00007 // Acknowledgments 
00008 //    The code is essentially a translation of
00009 //    RDBC/TSQLImporterClient by Valeriy Onuchin 21/03/2001
00010 //
00012 
00013 
00014 #include <fstream>
00015 #include <sstream>
00016 
00017 #include "TString.h"
00018 #include "TSystem.h"
00019 #include "TUrl.h"
00020 #include "TSocket.h"
00021 
00022 #include "DatabaseInterface/DbiAsciiTablePreparer.h"
00023 #include "MessageService/MsgService.h"
00024 #include "LeakChecker/Lea.h"
00025 
00026 ClassImp(DbiAsciiTablePreparer)
00027 
00028 //   Definition of static data members
00029 //   *********************************
00030 
00031 CVSID("$Id: DbiAsciiTablePreparer.cxx,v 1.4 2007/04/26 14:19:57 west Exp $");
00032 
00033 //   File static non-members functions
00034 //   *********************************
00035 
00036 //___________________________________________________________________
00037 TString Validate(const TString& str)
00038 {
00039    // internal use static func.
00040    // 
00041    // - Does validation of string as coulmn names/types, very primitive so far.
00042    // - Returns corrected column string 
00043 
00044    TString ret = str.Strip(TString::kBoth);
00045    Int_t spidx = 0;
00046    const char* s = ret.Data();
00047    
00048    if(s[0]=='\"' || s[strlen(s)-1]=='\"' ) {
00049       TString quote('\"');
00050       ret.ReplaceAll(quote,"");
00051       goto exit;
00052    }
00053    if( ret.IsNull() ||
00054       ((ret.Length()==1) && !isalpha(s[0]) ) ) return "wrong format";
00055 
00056    for (Ssiz_t i = 0; i < ret.Length(); i++) {
00057       if( !isalnum(s[i]) && !isspace(s[i]) && 
00058          s[i]!=')' && s[i]!='(' && s[i]!=',' &&
00059          s[i]!='_' && s[i]!='-' ) {
00060          return "wrong format";
00061       }
00062       if(isspace(s[i])) spidx = i;
00063    }
00064    
00065 exit:
00066    if(!spidx) ret += " TEXT NOT NULL";  
00067    return ret;   
00068 }
00069 
00070 //    Definition of all member functions (static or otherwise)
00071 //    *******************************************************
00072 //
00073 //    -  ordered: ctors, dtor, operators then in alphabetical order.
00074 
00075 
00076 //___________________________________________________________________
00077 
00078 DbiAsciiTablePreparer::DbiAsciiTablePreparer(const TString& url)
00079 {
00080    // ctor.
00081 
00082    LEA_CTOR    //Leak Checker
00083 
00084    MSG("Dbi", Msg::kVerbose) << "Creating DbiAsciiTablePreparer "  << (void*) this << endl;
00085 
00086    fUrl = new TUrl(url);
00087    fStatus = 0;
00088    TString host(fUrl->GetHost());
00089 
00090    TString str(fUrl->GetFile());
00091    fLocalFile = str;
00092 
00093    fTableName = TString(gSystem->BaseName(fLocalFile.Data()));
00094    TString ext = strrchr(fTableName.Data(),'.');
00095 
00096    if(!ext.IsNull()) {
00097       Int_t pidx = fTableName.Index(ext.Data());
00098       if(pidx>1) {
00099          fTableName =  fTableName(0,pidx);
00100       }
00101 
00102       fTableName.ReplaceAll(".","_");
00103    }
00104 
00105 
00106    if( host=="localhost" || host.IsNull() )  {
00107       fMustDeleteLocalFile = kFALSE;
00108       MSG("Dbi", Msg::kSynopsis) << "Preparing table " << fTableName
00109                                  << " from local file " << fLocalFile << endl;
00110    } else {
00111       fMustDeleteLocalFile = kTRUE;
00112       fLocalFile = Form("/tmp/%s%d",gSystem->BaseName(fUrl->GetFile()),gSystem->GetPid());
00113       MSG("Dbi", Msg::kSynopsis) << "Preparing table " << fTableName
00114                                  << " by downloading remote file " << fUrl->GetFile()
00115                                  << " from remote host " << host
00116                                  << " to local file " << fLocalFile << endl;
00117       GET(url);   // download 
00118    }
00119 
00120    fSkipLines = 1; // default , first line is a header describes the columns
00121 
00122    this->Init();
00123 }
00124 
00125 //___________________________________________________________________
00126 DbiAsciiTablePreparer::~DbiAsciiTablePreparer()
00127 {
00128    // dtor.
00129 
00130    LEA_DTOR    //Leak Checker
00131 
00132    MSG("Dbi", Msg::kVerbose) << "Destroying DbiAsciiTablePreparer "  << (void*) this << endl;
00133 
00134    Clean();
00135 }
00136 
00137 //___________________________________________________________________
00138 void DbiAsciiTablePreparer::Clean()
00139 {
00140    //
00141 
00142    if(fMustDeleteLocalFile) {
00143       gSystem->Unlink(fLocalFile.Data());
00144    }
00145    if(fUrl) delete fUrl; 
00146 }
00147 
00148 
00149 //___________________________________________________________________
00150 void DbiAsciiTablePreparer::GET(const TString& url)
00151 {
00152    // Download url into local temporary file
00153  
00154    TString str;
00155    const Int_t buflen=8192;
00156    static char buf[buflen];
00157 
00158    TString filename = url;
00159    filename.ReplaceAll(" ","");
00160 
00161    TUrl u(filename);
00162  
00163    TSocket s(u.GetHost(), u.GetPort());
00164 
00165    if (!s.IsValid()) {
00166      std::ostringstream oss;
00167      oss << "Unable to open socket to host " << u.GetHost()
00168          <<" port " <<  u.GetPort();
00169      fExceptionLog.AddEntry(oss.str());
00170      fStatus = HTTP_FORBIDDEN;
00171      return;
00172    }
00173 
00174    TString msg = Form("GET %s HTTP/1.0\015\012\015\012", u.GetFile());
00175    s.SendRaw(msg.Data(), msg.Length());
00176 
00177    while(s.RecvRaw(buf, buflen)>0) {         
00178       str += buf; 
00179       memset(buf,0,buflen);
00180    }
00181    s.Close();
00182 
00183    // cutoff HTTP header
00184    Int_t idx;
00185    idx = str.Index("\015\012\015\012");
00186    if(idx!=kNPOS) str = str(idx+4,str.Length()-idx-4);
00187 
00188    std::ofstream out_file(fLocalFile.Data());
00189    if(!out_file) {
00190      std::ostringstream oss;
00191      oss << "Unable to open to " << fLocalFile << " for writing";
00192      fExceptionLog.AddEntry(oss.str());
00193      fStatus = HTTP_FORBIDDEN;
00194    }
00195 
00196    else {
00197      out_file << str;
00198      if( out_file.fail() )  {
00199         std::ostringstream oss;
00200         oss << "Unable to write to " << fLocalFile;
00201         fExceptionLog.AddEntry(oss.str());
00202         fStatus = HTTP_FORBIDDEN;
00203      }
00204    }
00205    out_file.close();
00206    return;
00207 }
00208 
00209 //___________________________________________________________________
00210 Int_t DbiAsciiTablePreparer::Init()
00211 {
00212    // - read first line from local file 
00213    // - determine column names and types
00214 
00215    TString str;
00216 
00217    if(gSystem->AccessPathName(fLocalFile.Data())) {
00218       fStatus = HTTP_NOT_FOUND;
00219       str = "File ";
00220       str += fLocalFile + " not found";
00221       fExceptionLog.AddEntry(str.Data());
00222       return fStatus;
00223    }
00224 
00225    ifstream in_file(fLocalFile.Data());
00226 
00227    if( !in_file ) {
00228       in_file.close();
00229       fStatus = HTTP_FORBIDDEN;
00230       str = "You don't have read permission to ";
00231       str += fLocalFile;
00232       fExceptionLog.AddEntry(str.Data());
00233       return fStatus;
00234    }
00235    
00236    const Int_t buflen=8192;
00237    char buf[buflen];
00238 
00239    in_file.getline(buf,buflen);  // read first line         
00240    str = buf;
00241 
00242    if(str.IsNull()) {
00243       in_file.close(); // empty file
00244       fStatus = HTTP_NOT_ACCEPTABLE;
00245       str = "File ";
00246       str += fLocalFile + " is empty";
00247       fExceptionLog.AddEntry(str.Data());
00248       return fStatus;
00249    }
00250 
00251    TString tmp;
00252    Int_t i,k;
00253    Int_t ncols = 0;
00254    Bool_t wrongFormat = kFALSE;
00255 
00256    for( i=k=0; (i=str.Index(",",i))>0; k=i++ ) {
00257       ncols++;
00258       tmp = Validate(str(!k?0:k+1,!k?i:i-k-1));
00259       wrongFormat = wrongFormat || tmp.IsNull() || (tmp=="wrong format"); 
00260       if(!wrongFormat) fColumns +=  tmp + ",";
00261    } 
00262 
00263    ncols++;
00264    tmp = Validate(str(k+(ncols>1),str.Length())); // the rest of string
00265 
00266    wrongFormat = wrongFormat || (tmp=="wrong format"); 
00267    if(!wrongFormat)  {
00268       fColumns += tmp;
00269    }
00270    else {
00271       fColumns = "";
00272       for(i=1; i<ncols; i++) fColumns += Form("C%d TEXT NOT NULL,",i);
00273       fColumns += Form("C%d TEXT NOT NULL",ncols);
00274       fSkipLines = 0;
00275       MSG("Dbi",Msg::kWarning) << "Missing header line; treating first line as data" << endl;
00276    }
00277 
00278    in_file.close();
00279    return fStatus = HTTP_OK;
00280 }
00281 

Generated on Mon Feb 15 11:06:34 2010 for loon by  doxygen 1.3.9.1