TDbiAsciiTablePreparer.cxx

Go to the documentation of this file.
00001 // $Id: TDbiAsciiTablePreparer.cxx,v 1.1 2011/01/18 05:49:19 finch Exp $
00002 
00003 /////////////////////////////////////////////////////////////////////
00004 //
00005 // TDbiAsciiTablePreparer
00006 //
00007 // Acknowledgments
00008 //    The code is essentially a translation of
00009 //    RDBC/TSQLImporterClient by Valeriy Onuchin 21/03/2001
00010 //
00011 /////////////////////////////////////////////////////////////////////
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 "TDbiAsciiTablePreparer.hxx"
00023 #include <TSK_DBI_Log.hxx>
00024 #include <MsgFormat.h>
00025 using std::endl;
00026 
00027 ClassImp(TDbiAsciiTablePreparer)
00028 
00029 //   Definition of static data members
00030 //   *********************************
00031 
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 TDbiAsciiTablePreparer::TDbiAsciiTablePreparer(const TString& url)
00079 {
00080    // ctor.
00081 
00082 
00083    SK_DBI_Trace( "Creating TDbiAsciiTablePreparer "  << (void*) this << "  ");
00084 
00085    fUrl = new TUrl(url);
00086    fStatus = 0;
00087    TString host(fUrl->GetHost());
00088 
00089    TString str(fUrl->GetFile());
00090    fLocalFile = str;
00091 
00092    fTableName = TString(gSystem->BaseName(fLocalFile.Data()));
00093    TString ext = strrchr(fTableName.Data(),'.');
00094 
00095    if(!ext.IsNull()) {
00096       Int_t pidx = fTableName.Index(ext.Data());
00097       if(pidx>1) {
00098          fTableName =  fTableName(0,pidx);
00099       }
00100 
00101       fTableName.ReplaceAll(".","_");
00102    }
00103 
00104 
00105    if( host=="localhost" || host.IsNull() )  {
00106       fMustDeleteLocalFile = kFALSE;
00107       SK_DBI_Log( "Preparing table " << fTableName
00108                                  << " from local file " << fLocalFile << "  ");
00109    } else {
00110       fMustDeleteLocalFile = kTRUE;
00111       fLocalFile = Form("/tmp/%s%d",gSystem->BaseName(fUrl->GetFile()),gSystem->GetPid());
00112       SK_DBI_Log( "Preparing table " << fTableName
00113                                  << " by downloading remote file " << fUrl->GetFile()
00114                                  << " from remote host " << host
00115                                  << " to local file " << fLocalFile << "  ");
00116       GET(url);   // download
00117    }
00118 
00119    fSkipLines = 1; // default , first line is a header describes the columns
00120 
00121    this->Init();
00122 }
00123 
00124 //___________________________________________________________________
00125 TDbiAsciiTablePreparer::~TDbiAsciiTablePreparer()
00126 {
00127    // dtor.
00128 
00129 
00130    SK_DBI_Trace( "Destroying TDbiAsciiTablePreparer "  << (void*) this << "  ");
00131 
00132    Clean();
00133 }
00134 
00135 //___________________________________________________________________
00136 void TDbiAsciiTablePreparer::Clean()
00137 {
00138    //
00139 
00140    if(fMustDeleteLocalFile) {
00141       gSystem->Unlink(fLocalFile.Data());
00142    }
00143    if(fUrl) delete fUrl;
00144 }
00145 
00146 
00147 //___________________________________________________________________
00148 void TDbiAsciiTablePreparer::GET(const TString& url)
00149 {
00150    // Download url into local temporary file
00151 
00152    TString str;
00153    const Int_t buflen=8192;
00154    static char buf[buflen];
00155 
00156    TString filename = url;
00157    filename.ReplaceAll(" ","");
00158 
00159    TUrl u(filename);
00160 
00161    TSocket s(u.GetHost(), u.GetPort());
00162 
00163    if (!s.IsValid()) {
00164      std::ostringstream oss;
00165      oss << "Unable to open socket to host " << u.GetHost()
00166          <<" port " <<  u.GetPort();
00167      fExceptionLog.AddEntry(oss.str());
00168      fStatus = HTTP_FORBIDDEN;
00169      return;
00170    }
00171 
00172    TString msg = Form("GET %s HTTP/1.0\015\012\015\012", u.GetFile());
00173    s.SendRaw(msg.Data(), msg.Length());
00174 
00175    while(s.RecvRaw(buf, buflen)>0) {
00176       str += buf;
00177       memset(buf,0,buflen);
00178    }
00179    s.Close();
00180 
00181    // cutoff HTTP header
00182    Int_t idx;
00183    idx = str.Index("\015\012\015\012");
00184    if(idx!=kNPOS) str = str(idx+4,str.Length()-idx-4);
00185 
00186    std::ofstream out_file(fLocalFile.Data());
00187    if(!out_file) {
00188      std::ostringstream oss;
00189      oss << "Unable to open to " << fLocalFile << " for writing";
00190      fExceptionLog.AddEntry(oss.str());
00191      fStatus = HTTP_FORBIDDEN;
00192    }
00193 
00194    else {
00195      out_file << str;
00196      if( out_file.fail() )  {
00197         std::ostringstream oss;
00198         oss << "Unable to write to " << fLocalFile;
00199         fExceptionLog.AddEntry(oss.str());
00200         fStatus = HTTP_FORBIDDEN;
00201      }
00202    }
00203    out_file.close();
00204    return;
00205 }
00206 
00207 //___________________________________________________________________
00208 Int_t TDbiAsciiTablePreparer::Init()
00209 {
00210    // - read first line from local file
00211    // - determine column names and types
00212 
00213    TString str;
00214 
00215    if(gSystem->AccessPathName(fLocalFile.Data())) {
00216       fStatus = HTTP_NOT_FOUND;
00217       str = "File ";
00218       str += fLocalFile + " not found";
00219       fExceptionLog.AddEntry(str.Data());
00220       return fStatus;
00221    }
00222 
00223    ifstream in_file(fLocalFile.Data());
00224 
00225    if( !in_file ) {
00226       in_file.close();
00227       fStatus = HTTP_FORBIDDEN;
00228       str = "You don't have read permission to ";
00229       str += fLocalFile;
00230       fExceptionLog.AddEntry(str.Data());
00231       return fStatus;
00232    }
00233 
00234    const Int_t buflen=8192;
00235    char buf[buflen];
00236 
00237    in_file.getline(buf,buflen);  // read first line
00238    str = buf;
00239 
00240    if(str.IsNull()) {
00241       in_file.close(); // empty file
00242       fStatus = HTTP_NOT_ACCEPTABLE;
00243       str = "File ";
00244       str += fLocalFile + " is empty";
00245       fExceptionLog.AddEntry(str.Data());
00246       return fStatus;
00247    }
00248 
00249    TString tmp;
00250    Int_t i,k;
00251    Int_t ncols = 0;
00252    Bool_t wrongFormat = kFALSE;
00253 
00254    for( i=k=0; (i=str.Index(",",i))>0; k=i++ ) {
00255       ncols++;
00256       tmp = Validate(str(!k?0:k+1,!k?i:i-k-1));
00257       wrongFormat = wrongFormat || tmp.IsNull() || (tmp=="wrong format");
00258       if(!wrongFormat) fColumns +=  tmp + ",";
00259    }
00260 
00261    ncols++;
00262    tmp = Validate(str(k+(ncols>1),str.Length())); // the rest of string
00263 
00264    wrongFormat = wrongFormat || (tmp=="wrong format");
00265    if(!wrongFormat)  {
00266       fColumns += tmp;
00267    }
00268    else {
00269       fColumns = "";
00270       for(i=1; i<ncols; i++) fColumns += Form("C%d TEXT NOT NULL,",i);
00271       fColumns += Form("C%d TEXT NOT NULL",ncols);
00272       fSkipLines = 0;
00273       SK_DBI_Warn( "Missing header line; treating first line as data" << "  ");
00274    }
00275 
00276    in_file.close();
00277    return fStatus = HTTP_OK;
00278 }
00279 
00280 

Generated on 11 Aug 2013 for SKDatabase by  doxygen 1.6.1