00001 #ifndef Impala_Util_Database_h
00002 #define Impala_Util_Database_h
00003
00004 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00005
00006 #ifdef unix
00007 #include <sys/stat.h>
00008 #include <sys/types.h>
00009 #include <sys/resource.h>
00010 #else
00011 #include <direct.h>
00012 #endif
00013
00014 #include <vector>
00015 #include "Basis/CmdOptions.h"
00016 #include "Basis/FileNameTmp.h"
00017 #include "Util/ChannelPool.h"
00018 #include "Util/ReadIOBufferFromChannel.h"
00019 #include "Util/IOBufferFile.h"
00020 #include "Util/IOBufferChannel.h"
00021
00022 namespace Impala
00023 {
00024 namespace Util
00025 {
00026
00027
00028 class Database
00029 {
00030 public:
00031
00032 static Database&
00033 GetInstance()
00034 {
00035 static Database theDatabase;
00036 return theDatabase;
00037 }
00038
00039 Database()
00040 {
00041 Init("");
00042 }
00043
00044 Database(String setName)
00045 {
00046 Init(setName);
00047 }
00048
00049
00050 void
00051 SetDataPath(String data)
00052 {
00053 mDataString = data;
00054 mData.clear();
00055 mData = StringList(mDataString, ';');
00056 }
00057
00058 String
00059 GetDataPath()
00060 {
00061 return mDataString;
00062 }
00063
00064
00065 void
00066 SetOverride(bool override)
00067 {
00068 mOverride = override;
00069 }
00070
00071
00072
00073 String
00074 MakeDir(CString dir)
00075 {
00076 return DoMkDirPath(dir);
00077 }
00078
00079 String
00080 MakeDir(CString dir1, CString dir2)
00081 {
00082 return MakeDir(ConcatDir(dir1, dir2));
00083 }
00084
00085 String
00086 MakeDir(CString dir1, CString dir2, CString dir3)
00087 {
00088 return MakeDir(dir1, ConcatDir(dir2, dir3));
00089 }
00090
00091 String
00092 MakeDir(CString dir1, CString dir2, CString dir3, CString dir4)
00093 {
00094 return MakeDir(dir1, dir2, ConcatDir(dir3, dir4));
00095 }
00096
00097 String
00098 MakeDir(CString dir1, CString dir2, CString dir3, CString dir4, CString dir5)
00099 {
00100 return MakeDir(dir1, dir2, dir3, ConcatDir(dir4, dir5));
00101 }
00102
00103
00104
00105 String
00106 GetFilePath(CString file, bool toWrite, bool silent)
00107 {
00108 CString path = file;
00109 if (toWrite)
00110 return GetWritableFile(mData.begin(), mData.end(), path, silent);
00111 return GetReadableFile(mData.begin(), mData.end(), path, silent);
00112 }
00113
00114 String
00115 GetFilePath(CString dir, CString file, bool toWrite, bool silent)
00116 {
00117 String path = dir + "/" + file;
00118 if (toWrite)
00119 return GetWritableFile(mData.begin(), mData.end(), path, silent);
00120 return GetReadableFile(mData.begin(), mData.end(), path, silent);
00121 }
00122
00123 String
00124 GetFilePath(CString dir1, CString dir2, CString file, bool toWrite,
00125 bool silent)
00126 {
00127 String path = dir1 + "/" + dir2 + "/" + file;
00128 if (toWrite)
00129 return GetWritableFile(mData.begin(), mData.end(), path, silent);
00130 return GetReadableFile(mData.begin(), mData.end(), path, silent);
00131 }
00132
00133 String
00134 GetFilePath(CString dir1, CString dir2, CString dir3, CString file,
00135 bool toWrite, bool silent)
00136 {
00137 String path = dir1 + "/" + dir2 + "/" + dir3 + "/" + file;
00138 if (toWrite)
00139 return GetWritableFile(mData.begin(), mData.end(), path, silent);
00140 return GetReadableFile(mData.begin(), mData.end(), path, silent);
00141 }
00142
00143 String
00144 GetFilePath(CString dir1, CString dir2, CString dir3, CString dir4,
00145 CString file, bool toWrite, bool silent)
00146 {
00147 String path = dir1 + "/" + dir2 + "/" + dir3 + "/" + dir4 + "/" + file;
00148 if (toWrite)
00149 return GetWritableFile(mData.begin(), mData.end(), path, silent);
00150 return GetReadableFile(mData.begin(), mData.end(), path, silent);
00151 }
00152
00153 String
00154 GetFilePath(CString dir1, CString dir2, CString dir3, CString dir4,
00155 CString dir5, CString file, bool toWrite, bool silent)
00156 {
00157 String path = dir1 + "/" + dir2 + "/" + dir3 + "/" + dir4 + "/"
00158 + dir5 + "/" + file;
00159 if (toWrite)
00160 return GetWritableFile(mData.begin(), mData.end(), path, silent);
00161 return GetReadableFile(mData.begin(), mData.end(), path, silent);
00162 }
00163
00183 IOBuffer*
00184 GetIOBuffer(CString fileName, bool readMode, bool useMemoryIfLocal,
00185 String useLocalFileIfRemote, Int64 useLocalSizeIfRemote = 0,
00186 bool useIOBufferChannel = false)
00187 {
00188 IOBuffer* res = 0;
00189 ILOG_DEBUG("GetIOBuffer [" << fileName << "]");
00190 if (mDataChannel)
00191 {
00192 if (readMode)
00193 {
00194 if (useIOBufferChannel)
00195 {
00196 ILOG_DEBUG("GetIOBuffer: Read using Channel to " <<
00197 mDataServer << ": " << fileName);
00198 res = new IOBufferChannel(fileName, true, mDataChannel);
00199 }
00200 else
00201 {
00202 ILOG_DEBUG("GetIOBuffer: Read using File: " << fileName);
00203
00204
00205
00206
00207 if (useLocalFileIfRemote == "tmp")
00208 useLocalFileIfRemote = FileNameTmp();
00209 res = ReadIOBufferFromChannel(mDataChannel, fileName,
00210 useLocalFileIfRemote);
00211 }
00212 }
00213 else
00214 {
00215 if (useIOBufferChannel)
00216 {
00217 ILOG_DEBUG("GetIOBuffer: Write using Channel " << fileName);
00218 res = new IOBufferChannel(fileName, false, mDataChannel);
00219 }
00220 else if (useLocalFileIfRemote.empty())
00221 {
00222 ILOG_DEBUG("GetIOBuffer: Write using mem " << fileName);
00223 res = new IOBuffer(useLocalSizeIfRemote);
00224 }
00225 else
00226 {
00227 ILOG_DEBUG("GetIOBuffer: Write using File " << fileName);
00228 if (useLocalFileIfRemote == "tmp")
00229 useLocalFileIfRemote = FileNameTmp();
00230 res = new IOBufferFile(useLocalFileIfRemote, false, false);
00231 }
00232 if (!useIOBufferChannel)
00233 res->SetUseChannel(mDataChannel, fileName,
00234 useLocalFileIfRemote);
00235 }
00236 }
00237 else
00238 {
00239 res = new IOBufferFile(fileName, readMode, useMemoryIfLocal);
00240 }
00241
00242 if (res)
00243 {
00244 if (!res->Valid())
00245 {
00246 delete res;
00247 res = 0;
00248 }
00249 }
00250 return res;
00251 }
00252
00253 Channel*
00254 GetDataChannel()
00255 {
00256 return mDataChannel;
00257 }
00258
00259 void
00260 Dump() const
00261 {
00262 ILOG_INFO_ONCE("Dump: data=[" << mDataString << "] server=[" <<
00263 mDataServer << "]");
00264 }
00265
00266 private:
00267
00268 void
00269 Init(String setName)
00270 {
00271 CmdOptions& options = CmdOptions::GetInstance();
00272 mDataString = StringReplaceAll(options.GetString("data"), ":", ";", false);
00273 ILOG_DEBUG("'data' option externally specified: " << mDataString);
00274 String additionalData = options.GetString("data::"+setName, "");
00275 if (additionalData.empty() && !setName.empty())
00276 additionalData = "../" + FileNameBase(setName);
00277 if (!additionalData.empty())
00278 {
00279 mDataString = additionalData + ";" + mDataString;
00280 ILOG_INFO_ONCE("'data' option for " << setName <<
00281 " has been extended: " << mDataString);
00282 }
00283 mData = StringList(mDataString, ';');
00284 mDataServer = options.GetString("dataServer");
00285 String replaceDataServer = options.GetString("dataServer::"+setName, "");
00286 if (!replaceDataServer.empty())
00287 {
00288 mDataServer = replaceDataServer;
00289 ILOG_INFO_ONCE("server for " << setName << " is " << mDataServer);
00290 }
00291 mDataChannel = 0;
00292 if (!mDataServer.empty())
00293 {
00294 ILOG_INFO_ONCE("Retrieving channel to server " << mDataServer);
00295 String passFile = options.GetString("passwordFile");
00296 mDataChannel = ChannelPool::Instance().Get(mDataServer, passFile);
00297 }
00298 mOverride = options.GetBool("override");
00299 #ifdef WIN32
00300
00301 _setmaxstdio(2048);
00302 #endif
00303 #ifdef unix
00304 rlimit lim;
00305 getrlimit(RLIMIT_NOFILE, &lim);
00306 lim.rlim_cur = 2048;
00307 setrlimit(RLIMIT_NOFILE, &lim);
00308 #endif
00309 }
00310
00311
00312
00313 void
00314 DoMkDir(CString dir)
00315 {
00316 #ifdef unix
00317 mode_t m = 0755;
00318 mkdir(dir.c_str(), m);
00319 #else
00320 mkdir(dir.c_str());
00321 #endif
00322 }
00323
00324 String
00325 DoMkDirPath(CString dir)
00326 {
00327 if (mDataChannel)
00328 return DoMkDirPathServer(dir);
00329
00330 return DoMkDirPathLocal(ConcatDir(*mData.begin(), dir));
00331 }
00332
00333 String
00334 DoMkDirPathLocal(CString dirWithBackSlashes)
00335 {
00336 String dir = StringReplaceAll(dirWithBackSlashes, "\\", "/");
00337 ILOG_DEBUG("DoMkDirPath: " << dir);
00338 StringList subDirs(dir, '/');
00339 String path("");
00340 if (dir[0] == '/')
00341 path = String("/");
00342 for (StringListCI i=subDirs.begin() ; i!=subDirs.end() ; i++)
00343 {
00344 CString subDir = *i;
00345 ILOG_DEBUG(" DoMkDirPath: subDir = " << subDir);
00346 if (subDir.size() == 0)
00347 continue;
00348 if ((path.size() > 0) && (*path.rbegin() != '/'))
00349 path = path + "/";
00350 path = path + *i;
00351 DoMkDir(path);
00352 }
00353 return path;
00354 }
00355
00356 String
00357 DoMkDirPathServer(CString dir)
00358 {
00359 char* buf = mDataChannel->Buffer();
00360 sprintf(buf, "domkdirpath \"%s\" \"%s\"\0", dir.c_str(), mDataString.c_str());
00361 int len = mDataChannel->SendRequest(strlen(buf)+1);
00362 if (mDataChannel->LastSendHadError())
00363 return "";
00364 buf[len] = 0;
00365 String res(buf);
00366 ILOG_DEBUG("Got dir [" << res << "]");
00367 return res;
00368 }
00369
00370 String
00371 GetReadableFile(StringListCI begin, StringListCI end, CString file,
00372 bool silent)
00373 {
00374 if (mDataChannel)
00375 return GetReadableFileServer(file, silent);
00376 return GetReadableFileLocal(begin, end, file, silent);
00377 }
00378
00379 String
00380 GetReadableFileLocal(StringListCI begin, StringListCI end, CString file,
00381 bool silent)
00382 {
00383 StringListCI i;
00384 for (i=begin ; i!=end ; i++)
00385 {
00386 String path = *i + "/" + file;
00387 ILOG_DEBUG("GetReadableFile: trying " << path);
00388 if (IOBufferFile::FileExists(path))
00389 return path;
00390 }
00391
00392 if (!silent)
00393 {
00394 ILOG_ERROR("Unable to find " << file << " in path ");
00395 for (i=begin ; i!=end ; i++)
00396 ILOG_INFO(" " << *i);
00397 }
00398 return String("");
00399 }
00400
00401 String
00402 GetReadableFileServer(CString file, bool silent)
00403 {
00404 char* buf = mDataChannel->Buffer();
00405 sprintf(buf, "getreadablefile \"%s\" \"%s\" %d\0", file.c_str(),
00406 mDataString.c_str(), silent);
00407 int len = mDataChannel->SendRequest(strlen(buf)+1);
00408 if (mDataChannel->LastSendHadError())
00409 return "";
00410 buf[len] = 0;
00411 String res(buf);
00412 ILOG_DEBUG("Got file [" << res << "] from " << mDataServer);
00413 return res;
00414 }
00415
00416 String
00417 GetWritableFile(StringListCI begin, StringListCI end, CString file,
00418 bool silent)
00419 {
00420 if (mDataChannel)
00421 return GetWritableFileServer(file, silent);
00422 return GetWritableFileLocal(begin, end, file, silent);
00423 }
00424
00425 String
00426 GetWritableFileLocal(StringListCI begin, StringListCI end, CString file,
00427 bool silent)
00428 {
00429 if (begin == end)
00430 {
00431 ILOG_ERROR("GetWritableFile: no search path");
00432 return String("");
00433 }
00434 String path = *begin + "/" + file;
00435 ILOG_DEBUG("GetWritableFile: trying " << path);
00436 if (IOBufferFile::FileExists(path))
00437 {
00438 if (! mOverride)
00439 {
00440 if (!silent)
00441 ILOG_ERROR(path << " already exists, will not override!");
00442 return String("");
00443 }
00444 }
00445 return path;
00446 }
00447
00448 String
00449 GetWritableFileServer(CString file, bool silent)
00450 {
00451 char* buf = mDataChannel->Buffer();
00452 sprintf(buf, "getwritablefile \"%s\" \"%s\" %d %d\0", file.c_str(),
00453 mDataString.c_str(), silent, mOverride);
00454 int len = mDataChannel->SendRequest(strlen(buf)+1);
00455 if (mDataChannel->LastSendHadError())
00456 return "";
00457 buf[len] = 0;
00458 String res(buf);
00459 ILOG_DEBUG("Got file [" << res << "] from " << mDataServer);
00460 return res;
00461 }
00462
00463 String ConcatDir(CString dir, CString subDir)
00464 {
00465 return (subDir.empty() ? dir : (dir.empty() ? subDir : (dir + "/" + subDir)));
00466 }
00467
00468 bool mOverride;
00469 String mDataString;
00470 StringList mData;
00471 String mDataServer;
00472 Channel* mDataChannel;
00473
00474 ILOG_VAR_DEC;
00475 };
00476
00477 ILOG_VAR_INIT(Database, Impala.Util);
00478
00479 }
00480 }
00481
00482 #endif // REPOSITORY_USED
00483
00484 #endif