TDbiAsciiTablePreparer.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00030
00031
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 TDbiAsciiTablePreparer::TDbiAsciiTablePreparer(const TString& url)
00079 {
00080
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);
00117 }
00118
00119 fSkipLines = 1;
00120
00121 this->Init();
00122 }
00123
00124
00125 TDbiAsciiTablePreparer::~TDbiAsciiTablePreparer()
00126 {
00127
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
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
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
00211
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);
00238 str = buf;
00239
00240 if(str.IsNull()) {
00241 in_file.close();
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()));
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