1 /*============================================================================== 2 * 3 * PUBLIC DOMAIN NOTICE 4 * National Center for Biotechnology Information 5 * 6 * This software/database is a "United States Government Work" under the 7 * terms of the United States Copyright Act. It was written as part of 8 * the author's official duties as a United States Government employee and 9 * thus cannot be copyrighted. This software/database is freely available 10 * to the public for use. The National Library of Medicine and the U.S. 11 * Government have not placed any restriction on its use or reproduction. 12 * 13 * Although all reasonable efforts have been taken to ensure the accuracy 14 * and reliability of the software and data, the NLM and the U.S. 15 * Government do not and cannot warrant the performance or results that 16 * may be obtained by using this software or data. The NLM and the U.S. 17 * Government disclaim all warranties, express or implied, including 18 * warranties of performance, merchantability or fitness for any particular 19 * purpose. 20 * 21 * Please cite the author in any work or product based on this material. 22 * 23 * =========================================================================== 24 * 25 */ 26 27 // helper.h 28 #include <exception> 29 #include <string.h> 30 31 #include <stdint.h> 32 33 #include <vdb/manager.h> 34 #include <vdb/schema.h> 35 #include <vdb/database.h> 36 #include <vdb/table.h> 37 #include <vdb/cursor.h> 38 #include <klib/printf.h> 39 #include <klib/vector.h> 40 #include <kapp/args.h> 41 #include <kapp/progressbar.h> 42 #include <kapp/log-xml.h> 43 44 45 #ifndef countof 46 #define countof(arr) (sizeof(arr)/sizeof(arr[0])) 47 #endif 48 49 #ifdef _WIN32 50 #pragma warning (disable:4503) 51 #endif 52 53 #define USING_UINT64_BITMAP 0 54 #define MANAGER_WRITABLE 1 55 #define DEBUG_PRINT 0 56 57 namespace KLib 58 { 59 class CKVector 60 { 61 public: 62 CKVector(); 63 CKVector (CKVector const& x); 64 CKVector& operator= (CKVector const& x); 65 ~CKVector(); 66 67 void SetBool (uint64_t key, bool value); 68 void VisitBool (rc_t ( * f ) ( uint64_t key, bool value, void *user_data ), void *user_data) const; 69 70 private: 71 void Make(); 72 void Release(); 73 74 ::KVector* m_pSelf; 75 }; 76 } 77 78 namespace Utils 79 { 80 class CErrorMsg : public std::exception 81 { 82 public: 83 CErrorMsg(rc_t rc, char const* fmt_str, ...); 84 85 rc_t getRC() const; 86 virtual char const* what() const throw(); 87 88 private: 89 char m_szDescr[256]; 90 rc_t m_rc; 91 }; 92 atoi_t(char const * str_val)93 template <typename T> T atoi_t ( char const* str_val ) 94 { 95 if ( str_val [0] == '\0' ) 96 throw Utils::CErrorMsg(0, "atoi_t: invalid input string (empty)"); 97 98 size_t i = 0; 99 char sign = '+'; 100 if ( str_val[0] == '-' || str_val[0] == '+' ) 101 { 102 ++i; 103 sign = str_val[0]; 104 } 105 106 T ret = 0; 107 for (; str_val[i] != '\0'; ++i ) 108 { 109 if ( str_val[i] < '0' || str_val[i] > '9' ) 110 throw Utils::CErrorMsg(0, "atoi_t: invalid input string \"%s\" (invalid character: '%c' at pos=%zu)", str_val, str_val[i], i+1); 111 ret = ret*10 + str_val[i] - '0'; 112 } 113 114 return sign == '-' ? -ret : ret; 115 } 116 atou_t(char const * str_val)117 template <typename T> T atou_t ( char const* str_val ) 118 { 119 if ( str_val [0] == '\0' ) 120 throw Utils::CErrorMsg(0, "atou_t: invalid input string (empty)"); 121 122 T ret = 0; 123 for ( size_t i = 0; str_val[i] != '\0'; ++i ) 124 { 125 if ( str_val[i] < '0' || str_val[i] > '9' ) 126 throw Utils::CErrorMsg(0, "atoi_t: invalid input string \"%s\" (invalid character: '%c' at pos=%zu)", str_val, str_val[i], i+1); 127 ret = ret*10 + str_val[i] - '0'; 128 } 129 130 return ret; 131 } 132 133 enum ErrorHandlerCode 134 { 135 rcUnknown = -2, 136 rcErrorStdExc = -1, 137 rcInvalid = -99 138 // value > 0 means rc_t returned from a VDB-function 139 // zero shall not be returned 140 }; 141 142 // This function must be called inside catch block only 143 // if bSilent == true then produce no output, only return ErrorHandlerCode 144 // pErrDesc and sizeErrDesc - the buffer to write error description to (NULL - OK) 145 int64_t HandleException ( bool bSilent, char* pErrDesc, size_t sizeErrDesc ); 146 } 147 148 namespace VDBObjects 149 { 150 /* functor to remove trailing '\n' from char reads */ 151 template<typename T> class CPostReadAction 152 { 153 T* m_pBuf; 154 uint32_t m_nCount; 155 public: CPostReadAction(T * pBuf,uint32_t nCount)156 CPostReadAction(T* pBuf, uint32_t nCount) : m_pBuf(pBuf), m_nCount(nCount) {} 157 void operator()() const; 158 }; operator()159 template<typename T> inline void CPostReadAction<T>::operator()() const {} operator()160 template<> inline void CPostReadAction<char>::operator()() const { m_pBuf[m_nCount] = '\0'; } operator()161 template<> inline void CPostReadAction<unsigned char>::operator()() const { m_pBuf[m_nCount] = '\0'; } 162 163 class CVCursor; 164 class CVTable; 165 class CVDatabase; 166 class CVSchema; 167 168 ///////////////////////////////////////////////////////////////////////////////// 169 170 class CVDBManager 171 { 172 public: 173 CVDBManager(); 174 ~CVDBManager(); 175 CVDBManager(CVDBManager const& x); 176 CVDBManager& operator=(CVDBManager const& x); 177 178 void Make(); 179 void Release(); 180 CVDatabase OpenDB ( char const* pszDBName ) const; 181 CVDatabase CreateDB ( CVSchema const& schema, char const* pszTypeDesc, ::KCreateMode cmode, char const* pszPath ); 182 CVSchema MakeSchema () const; 183 184 private: 185 ::VDBManager* m_pSelf; 186 }; 187 188 ///////////////////////////////////////////////////////////////////////////////// 189 190 class CVSchema 191 { 192 public: 193 friend CVSchema CVDBManager::MakeSchema () const; 194 friend CVDatabase CVDBManager::CreateDB ( CVSchema const& schema, char const* pszTypeDesc, ::KCreateMode cmode, char const* pszPath ); 195 196 CVSchema(); 197 ~CVSchema(); 198 CVSchema(CVSchema const& x); 199 CVSchema& operator=(CVSchema const& x); 200 201 void Make(); 202 void Release(); 203 void VSchemaParseFile(char const* pszFilePath); 204 205 private: 206 void Clone ( CVSchema const& x ); 207 ::VSchema* m_pSelf; 208 }; 209 210 ///////////////////////////////////////////////////////////////////////////////// 211 212 class CVDatabase 213 { 214 public: 215 friend CVDatabase CVDBManager::OpenDB ( char const* pszDBName ) const; 216 friend CVDatabase CVDBManager::CreateDB ( CVSchema const& schema, char const* pszTypeDesc, ::KCreateMode cmode, char const* pszPath ); 217 218 CVDatabase(); 219 ~CVDatabase(); 220 CVDatabase(CVDatabase const& x); 221 CVDatabase& operator=(CVDatabase const& x); 222 223 void Release(); 224 CVTable OpenTable ( char const* pszTableName ) const; 225 CVTable CreateTable ( char const* pszTableName ); 226 void ColumnCreateParams ( ::KCreateMode cmode, ::KChecksum checksum, size_t pgsize ); 227 228 private: 229 void Clone(CVDatabase const& x); 230 ::VDatabase* m_pSelf; 231 }; 232 233 ////////////////////////////////////////////////////////////// 234 235 class CVTable 236 { 237 public: 238 friend CVTable CVDatabase::OpenTable(char const* pszTableName) const; 239 friend CVTable CVDatabase::CreateTable ( char const* pszTableName ); 240 241 CVTable(); 242 ~CVTable(); 243 CVTable(CVTable const& x); 244 CVTable& operator=(CVTable const& x); 245 246 void Release(); 247 CVCursor CreateCursorRead ( size_t cache_size ) const; 248 CVCursor CreateCursorWrite ( ::KCreateMode mode ); 249 250 private: 251 void Clone(CVTable const& x); 252 ::VTable* m_pSelf; 253 }; 254 255 //////////////////////////////////////////////////////////////////////////// 256 257 class CVCursor 258 { 259 public: 260 friend CVCursor CVTable::CreateCursorRead ( size_t cache_size ) const; 261 friend CVCursor CVTable::CreateCursorWrite (::KCreateMode mode); 262 263 CVCursor(); 264 ~CVCursor(); 265 CVCursor(CVCursor const& x); 266 CVCursor& operator=(CVCursor const& x); 267 268 void Release(); 269 void PermitPostOpenAdd() const; 270 #if MANAGER_WRITABLE != 0 271 void InitColumnIndex(char const* const* ColumnNames, uint32_t* pColumnIndex, size_t nCount, bool set_default); 272 #else 273 void InitColumnIndex(char const* const* ColumnNames, uint32_t* pColumnIndex, size_t nCount); 274 #endif 275 void Open() const; 276 void GetIdRange(int64_t& idFirstRow, uint64_t& nRowCount) const; 277 ReadItems(int64_t idRow,uint32_t idxCol,T * pBuf,uint32_t nBufLen)278 template <typename T> uint32_t ReadItems (int64_t idRow, uint32_t idxCol, T* pBuf, uint32_t nBufLen) const 279 { 280 uint32_t nItemsRead = 0; 281 282 rc_t rc = ::VCursorReadDirect(m_pSelf, idRow, idxCol, 8*sizeof(T), pBuf, nBufLen, &nItemsRead); 283 if (rc) 284 throw Utils::CErrorMsg(rc, "VCursorReadDirect: row_id=%ld, idxCol=%u", idRow, idxCol); 285 286 //CPostReadAction<T>(pBuf, nItemsRead)(); 287 288 return nItemsRead; 289 } 290 Write(uint32_t idxCol,T const * pBuf,uint64_t count)291 template <typename T> void Write (uint32_t idxCol, T const* pBuf, uint64_t count) 292 { 293 rc_t rc = ::VCursorWrite ( m_pSelf, idxCol, 8 * sizeof(T), pBuf, 0, count ); 294 if (rc) 295 throw Utils::CErrorMsg(rc, "VCursorWrite: idxCol=%u", idxCol); 296 } 297 298 int64_t GetRowId () const; 299 void SetRowId (int64_t row_id) const; 300 void OpenRow () const; 301 void CommitRow (); 302 void RepeatRow ( uint64_t count ); 303 void CloseRow () const; 304 void Commit (); 305 306 private: 307 void Clone(CVCursor const& x); 308 ::VCursor* m_pSelf; 309 }; 310 } 311 312 /////////////////////// 313 314 namespace KApp 315 { 316 class CArgs; 317 class CXMLLogger 318 { 319 public: 320 CXMLLogger ( CArgs const& args ); 321 CXMLLogger (CXMLLogger const& x); 322 CXMLLogger& operator= (CXMLLogger const& x); 323 ~CXMLLogger (); 324 325 void Make ( CArgs const& args ); 326 327 private: 328 void Release (); 329 330 XMLLogger const* m_pSelf; 331 }; 332 333 ///////////////////////////////////////// 334 335 class CArgs 336 { 337 public: 338 friend void CXMLLogger::Make ( CArgs const& args ); 339 340 CArgs ( int argc, char** argv, ::OptDef const* pOptions, size_t option_count ); 341 CArgs ( int argc, char** argv, ::OptDef const* pOptions1, size_t option_count1, ::OptDef const* pOptions2, size_t option_count2 ); 342 CArgs ( CArgs const& x ); 343 CArgs& operator= ( CArgs const& x ); 344 ~CArgs (); 345 346 ::Args const* GetArgs () const; 347 uint32_t GetParamCount () const; 348 char const* GetParamValue ( uint32_t iteration ) const; 349 uint32_t GetOptionCount ( char const* option_name ) const; 350 char const* GetOptionValue ( char const* option_name, uint32_t iteration ) const; 351 GetOptionValueInt(char const * option_name,uint32_t iteration)352 template <typename T> T GetOptionValueInt ( char const* option_name, uint32_t iteration ) const 353 { 354 char const* str_val = GetOptionValue ( option_name, iteration ); 355 return Utils::atoi_t <T> ( str_val ); 356 } GetOptionValueUInt(char const * option_name,uint32_t iteration)357 template <typename T> T GetOptionValueUInt ( char const* option_name, uint32_t iteration ) const 358 { 359 char const* str_val = GetOptionValue ( option_name, iteration ); 360 return Utils::atou_t <T> ( str_val ); 361 } 362 363 private: 364 365 void MakeAndHandle ( int argc, char** argv, ::OptDef const* pOptions, size_t option_count ); 366 // TODO: it's better to make ::ArgsMakeAndHandle be able to take va_list 367 void MakeAndHandle ( int argc, char** argv, ::OptDef const* pOptions1, size_t option_count1, ::OptDef const* pOptions2, size_t option_count2 ); 368 void Release (); 369 370 ::Args* m_pSelf; 371 }; 372 373 class CProgressBar 374 { 375 public: 376 CProgressBar ( uint64_t size ); 377 CProgressBar ( CProgressBar const& x ); 378 CProgressBar& operator= ( CProgressBar const& x ); 379 ~CProgressBar (); 380 381 void Append ( uint64_t chunk ); 382 void Process ( uint64_t chunk, bool force_report ); 383 384 private: 385 void Make ( uint64_t size ); 386 void Release (); 387 388 KLoadProgressbar const* m_pSelf; 389 }; 390 } 391