00001
00002
00004
00005
00006
00007
00008
00009
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
00029
00030
00031 CVSID("$Id: DbiAsciiTablePreparer.cxx,v 1.4 2007/04/26 14:19:57 west Exp $");
00032
00033
00034
00035
00036
00037 TString Validate(const TString& str)
00038 {
00039
00040
00041
00042
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
00071
00072
00073
00074
00075
00076
00077
00078 DbiAsciiTablePreparer::DbiAsciiTablePreparer(const TString& url)
00079 {
00080
00081
00082 LEA_CTOR
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);
00118 }
00119
00120 fSkipLines = 1;
00121
00122 this->Init();
00123 }
00124
00125
00126 DbiAsciiTablePreparer::~DbiAsciiTablePreparer()
00127 {
00128
00129
00130 LEA_DTOR
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
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
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
00213
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);
00240 str = buf;
00241
00242 if(str.IsNull()) {
00243 in_file.close();
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()));
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