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.cpp
28 
29 #include "helper.h"
30 
31 #include <algorithm>
32 #include <stdio.h>
33 #include <iostream>
34 
35 #include <vdb/vdb-priv.h>
36 #include <klib/rc.h>
37 
38 #ifdef _WIN32
39 #pragma warning (disable:4503)
40 #endif
41 
42 // TODO: remove printfs
43 namespace KLib
44 {
CKVector()45     CKVector::CKVector() : m_pSelf(NULL)
46     {
47         Make();
48     }
49 
~CKVector()50     CKVector::~CKVector()
51     {
52         Release();
53     }
54 
Make()55     void CKVector::Make()
56     {
57         if (m_pSelf)
58             throw Utils::CErrorMsg (0, "Duplicated call to KVectorMake");
59 
60         rc_t rc = ::KVectorMake(&m_pSelf);
61         if (rc)
62             throw Utils::CErrorMsg(rc, "KVectorMake");
63 #if DEBUG_PRINT != 0
64         printf("Created KVector %p\n", m_pSelf);
65 #endif
66     }
67 
Release()68     void CKVector::Release()
69     {
70         if (m_pSelf)
71         {
72 #if DEBUG_PRINT != 0
73             printf("Releasing KVector %p\n", m_pSelf);
74 #endif
75             ::KVectorRelease(m_pSelf);
76             m_pSelf = NULL;
77         }
78     }
79 
80     size_t const RECORD_SIZE_IN_BITS = 2;
81     uint64_t const BIT_SET_MASK = 0x2;
82     uint64_t const BIT_VALUE_MASK = 0x1;
83     uint64_t const BIT_RECORD_MASK = BIT_SET_MASK | BIT_VALUE_MASK;
84 
SetBool(uint64_t key,bool value)85     void CKVector::SetBool(uint64_t key, bool value)
86     {
87 #if USING_UINT64_BITMAP == 1
88         uint64_t stored_bits = 0;
89         uint64_t key_qword = key / 64;
90         uint64_t key_bit = key % 64;
91         rc_t rc = ::KVectorGetU64 ( m_pSelf, key_qword, &stored_bits );
92         bool first_time = rc == RC ( rcCont, rcVector, rcAccessing, rcItem, rcNotFound ); // 0x1e615458
93         if ( !first_time && rc )
94             throw Utils::CErrorMsg(rc, "KVectorGetU64");
95 
96         uint64_t new_bit = (uint64_t)value << key_bit;
97         uint64_t stored_bit = (uint64_t)1 << key_bit & stored_bits;
98 
99         if ( first_time || new_bit != stored_bit )
100         {
101             if ( new_bit )
102                 stored_bits |= new_bit;
103             else
104                 stored_bits &= ~new_bit;
105 
106             rc_t rc = ::KVectorSetU64 ( m_pSelf, key_qword, stored_bits );
107             if (rc)
108                 throw Utils::CErrorMsg(rc, "KVectorSetU64");
109         }
110 #elif USING_UINT64_BITMAP == 2
111         uint64_t stored_bits = 0;
112         uint64_t key_qword = key / (sizeof(stored_bits) * 8 / RECORD_SIZE_IN_BITS);
113         uint64_t bit_offset_in_qword = (key % (sizeof(stored_bits) * 8 / RECORD_SIZE_IN_BITS)) * RECORD_SIZE_IN_BITS;
114         rc_t rc = ::KVectorGetU64 ( m_pSelf, key_qword, &stored_bits );
115         bool first_time = rc == RC ( rcCont, rcVector, rcAccessing, rcItem, rcNotFound ); // 0x1e615458;
116         if ( !first_time && rc )
117             throw Utils::CErrorMsg(rc, "KVectorGetU64");
118 
119         uint64_t new_bit_record = (BIT_SET_MASK | (uint64_t)value) << bit_offset_in_qword;
120         uint64_t stored_bit_record = (uint64_t)BIT_RECORD_MASK << bit_offset_in_qword & stored_bits;
121 
122         if ( first_time || new_bit_record != stored_bit_record )
123         {
124             stored_bits &= ~((uint64_t)BIT_RECORD_MASK << bit_offset_in_qword); // clear stored record to assign a new value by bitwise OR
125             stored_bits |= new_bit_record;
126 
127             rc_t rc = ::KVectorSetU64 ( m_pSelf, key_qword, stored_bits );
128             if (rc)
129                 throw Utils::CErrorMsg(rc, "KVectorSetU64");
130         }
131 #else
132 
133         rc_t rc = ::KVectorSetBool ( m_pSelf, key, value );
134         if (rc)
135             throw Utils::CErrorMsg(rc, "KVectorSetBool");
136 #endif
137     }
138 
139     struct UserDataU64toBool
140     {
141         rc_t ( * f ) ( uint64_t key, bool value, void *user_data );
142         void* user_data;
143     };
144 #if USING_UINT64_BITMAP == 1
VisitU64toBoolAdapter(uint64_t key,uint64_t value,void * user_data)145     rc_t VisitU64toBoolAdapter ( uint64_t key, uint64_t value, void *user_data )
146     {
147         rc_t ( * bool_callback ) ( uint64_t key, bool value, void *user_data );
148         bool_callback = ((UserDataU64toBool*) user_data) -> f;
149         void* original_user_data = ((UserDataU64toBool*) user_data) -> user_data;
150 
151         rc_t rc = 0;
152         for ( size_t i = 0; i < sizeof (value) * 8; ++i )
153         {
154             rc = bool_callback ( key * 64 + i, (bool) ((uint64_t)1 << i & value), original_user_data );
155             if ( rc )
156                 return rc;
157         }
158         return rc;
159     }
160 #elif USING_UINT64_BITMAP == 2
VisitU64toBoolAdapter(uint64_t key,uint64_t value,void * user_data)161     rc_t VisitU64toBoolAdapter ( uint64_t key, uint64_t value, void *user_data )
162     {
163         rc_t ( * bool_callback ) ( uint64_t key, bool value, void *user_data );
164         bool_callback = ((UserDataU64toBool*) user_data) -> f;
165         void* original_user_data = ((UserDataU64toBool*) user_data) -> user_data;
166 
167         rc_t rc = 0;
168         for ( size_t i = 0; i < sizeof (value) * 8 / RECORD_SIZE_IN_BITS; ++i )
169         {
170             uint64_t key_bool = key * sizeof(value) * 8 / RECORD_SIZE_IN_BITS + i;
171             uint64_t record = value >> i * RECORD_SIZE_IN_BITS & BIT_RECORD_MASK;
172             if ( record & BIT_SET_MASK )
173             {
174                 rc = bool_callback ( key_bool, (bool) (record & BIT_VALUE_MASK), original_user_data );
175                 if ( rc )
176                     return rc;
177             }
178         }
179         return rc;
180     }
181 #endif
182 
VisitBool(rc_t (* f)(uint64_t key,bool value,void * user_data),void * user_data) const183     void CKVector::VisitBool(rc_t ( * f ) ( uint64_t key, bool value, void *user_data ), void *user_data) const
184     {
185 #if USING_UINT64_BITMAP == 1
186         UserDataU64toBool user_data_adapter = { f, user_data };
187         ::KVectorVisitU64 ( m_pSelf, false, VisitU64toBoolAdapter, &user_data_adapter );
188 #elif USING_UINT64_BITMAP == 2
189         UserDataU64toBool user_data_adapter = { f, user_data };
190         ::KVectorVisitU64 ( m_pSelf, false, VisitU64toBoolAdapter, &user_data_adapter );
191 #else
192         ::KVectorVisitBool ( m_pSelf, false, f, user_data );
193 #endif
194     }
195 }
196 
197 ///////////////////////////////////////////////////////////////
198 
199 namespace VDBObjects
200 {
CVCursor()201     CVCursor::CVCursor() : m_pSelf(NULL)
202     {}
203 
~CVCursor()204     CVCursor::~CVCursor()
205     {
206         Release();
207     }
208 
CVCursor(CVCursor const & x)209     CVCursor::CVCursor(CVCursor const& x)
210     {
211         Clone(x);
212     }
213 
operator =(CVCursor const & x)214     CVCursor& CVCursor::operator=(CVCursor const& x)
215     {
216         if (m_pSelf)
217             Release();
218 
219         Clone(x);
220         return *this;
221     }
222 
Release()223     void CVCursor::Release()
224     {
225         if (m_pSelf)
226         {
227 #if DEBUG_PRINT != 0
228             printf("Releasing VCursor %p\n", m_pSelf);
229 #endif
230             ::VCursorRelease(m_pSelf);
231             m_pSelf = NULL;
232         }
233     }
234 
Clone(CVCursor const & x)235     void CVCursor::Clone(CVCursor const& x)
236     {
237         m_pSelf = x.m_pSelf;
238         ::VCursorAddRef ( m_pSelf );
239 #if DEBUG_PRINT != 0
240         printf ("CLONING VCursor %p\n", m_pSelf);
241 #endif
242     }
243 
Open() const244     void CVCursor::Open() const
245     {
246         rc_t rc = ::VCursorOpen(m_pSelf);
247         if (rc)
248             throw Utils::CErrorMsg(rc, "VCursorOpen");
249     }
250 
PermitPostOpenAdd() const251     void CVCursor::PermitPostOpenAdd() const
252     {
253         rc_t rc = ::VCursorPermitPostOpenAdd ( m_pSelf );
254         if (rc)
255             throw Utils::CErrorMsg(rc, "VCursorPermitPostOpenAdd");
256     }
257 
InitColumnIndex(char const * const * ColumnNames,uint32_t * pColumnIndex,size_t nCount,bool set_default)258     void CVCursor::InitColumnIndex(char const* const* ColumnNames, uint32_t* pColumnIndex, size_t nCount, bool set_default)
259     {
260         for (size_t i = 0; i < nCount; ++i)
261         {
262             rc_t rc = ::VCursorAddColumn(m_pSelf, & pColumnIndex[i], ColumnNames[i] );
263             if (rc)
264                 throw Utils::CErrorMsg(rc, "VCursorAddColumn - [%s]", ColumnNames[i]);
265 
266             if ( set_default )
267             {
268                 VTypedecl type;
269                 VTypedesc desc;
270                 uint32_t idx = pColumnIndex[i];
271 
272                 rc = ::VCursorDatatype ( m_pSelf, idx, & type, & desc );
273                 if (rc)
274                     throw Utils::CErrorMsg(rc, "VCursorDatatype (column idx=%u [%s])", idx, ColumnNames[i]);
275 
276                 uint32_t elem_bits = ::VTypedescSizeof ( & desc );
277                 if (rc)
278                     throw Utils::CErrorMsg(rc, "VTypedescSizeof (column idx=%u [%s])", idx, ColumnNames[i]);
279                 rc = ::VCursorDefault ( m_pSelf, idx, elem_bits, "", 0, 0 );
280                 if (rc)
281                     throw Utils::CErrorMsg(rc, "VCursorDefault (column idx=%u [%s])", idx, ColumnNames[i]);
282             }
283         }
284     }
285 
GetIdRange(int64_t & idFirstRow,uint64_t & nRowCount) const286     void CVCursor::GetIdRange(int64_t& idFirstRow, uint64_t& nRowCount) const
287     {
288         rc_t rc = ::VCursorIdRange(m_pSelf, 0, &idFirstRow, &nRowCount);
289         if (rc)
290             throw Utils::CErrorMsg(rc, "VCursorIdRange");
291     }
292 
GetRowId() const293     int64_t CVCursor::GetRowId () const
294     {
295         int64_t row_id;
296         rc_t rc = ::VCursorRowId ( m_pSelf, & row_id );
297         if (rc)
298             throw Utils::CErrorMsg(rc, "VCursorRowId");
299 
300         return row_id;
301     }
302 
SetRowId(int64_t row_id) const303     void CVCursor::SetRowId (int64_t row_id) const
304     {
305         rc_t rc = ::VCursorSetRowId ( m_pSelf, row_id );
306         if (rc)
307             throw Utils::CErrorMsg(rc, "VCursorSetRowId (%ld)", row_id);
308     }
309 
OpenRow() const310     void CVCursor::OpenRow () const
311     {
312         rc_t rc = ::VCursorOpenRow ( m_pSelf );
313         if (rc)
314             throw Utils::CErrorMsg(rc, "VCursorOpenRow");
315     }
316 
CommitRow()317     void CVCursor::CommitRow ()
318     {
319         rc_t rc = ::VCursorCommitRow ( m_pSelf );
320         if (rc)
321             throw Utils::CErrorMsg(rc, "VCursorCommitRow");
322     }
323 
RepeatRow(uint64_t count)324     void CVCursor::RepeatRow ( uint64_t count )
325     {
326         rc_t rc = ::VCursorRepeatRow ( m_pSelf, count );
327         if (rc)
328             throw Utils::CErrorMsg(rc, "VCursorRepeatRow (%lu)", count);
329     }
330 
CloseRow() const331     void CVCursor::CloseRow () const
332     {
333         rc_t rc = ::VCursorCloseRow ( m_pSelf );
334         if (rc)
335             throw Utils::CErrorMsg(rc, "VCursorCloseRow");
336     }
337 
Commit()338     void CVCursor::Commit ()
339     {
340         rc_t rc = ::VCursorCommit ( m_pSelf );
341         if (rc)
342             throw Utils::CErrorMsg(rc, "VCursorCommit");
343     }
344 
345 ///////////////////////////////////////////////////////////////////////////////////
346 
CVTable()347     CVTable::CVTable() : m_pSelf(NULL)
348     {
349     }
350 
~CVTable()351     CVTable::~CVTable()
352     {
353         Release();
354     }
355 
CVTable(CVTable const & x)356     CVTable::CVTable(CVTable const& x)
357     {
358         Clone(x);
359     }
360 
operator =(CVTable const & x)361     CVTable& CVTable::operator=(CVTable const& x)
362     {
363         if (m_pSelf)
364             Release();
365 
366         Clone(x);
367         return *this;
368     }
369 
Release()370     void CVTable::Release()
371     {
372         if (m_pSelf)
373         {
374 #if DEBUG_PRINT != 0
375             printf("Releasing VTable %p\n", m_pSelf);
376 #endif
377             ::VTableRelease(m_pSelf);
378             m_pSelf = NULL;
379         }
380     }
381 
Clone(CVTable const & x)382     void CVTable::Clone(CVTable const& x)
383     {
384         m_pSelf = x.m_pSelf;
385         ::VTableAddRef ( m_pSelf );
386 #if DEBUG_PRINT != 0
387         printf ("CLONING VTable %p\n", m_pSelf);
388 #endif
389     }
390 
CreateCursorRead(size_t cache_size) const391     CVCursor CVTable::CreateCursorRead ( size_t cache_size ) const
392     {
393         CVCursor cursor;
394         rc_t rc = ::VTableCreateCachedCursorRead(m_pSelf, const_cast<VCursor const**>(& cursor.m_pSelf), cache_size);
395         if (rc)
396             throw Utils::CErrorMsg(rc, "VTableCreateCachedCursorRead (%zu)", cache_size);
397 
398 #if DEBUG_PRINT != 0
399         printf("Created cursor (rd) %p\n", cursor.m_pSelf);
400 #endif
401         return cursor;
402     }
403 
CreateCursorWrite(::KCreateMode mode)404     CVCursor CVTable::CreateCursorWrite (::KCreateMode mode)
405     {
406         CVCursor cursor;
407         rc_t rc = ::VTableCreateCursorWrite ( m_pSelf, & cursor.m_pSelf, mode );
408         if (rc)
409             throw Utils::CErrorMsg(rc, "VTableCreateCursorWrite");
410 
411 #if DEBUG_PRINT != 0
412         printf("Created cursor (wr) %p\n", cursor.m_pSelf);
413 #endif
414         return cursor;
415     }
416 
417 //////////////////////////////////////////////////////////////////////
418 
CVDatabase()419     CVDatabase::CVDatabase() : m_pSelf(NULL)
420     {}
421 
~CVDatabase()422     CVDatabase::~CVDatabase()
423     {
424         Release();
425     }
426 
CVDatabase(CVDatabase const & x)427     CVDatabase::CVDatabase(CVDatabase const& x)
428     {
429         Clone(x);
430     }
431 
operator =(CVDatabase const & x)432     CVDatabase& CVDatabase::operator=(CVDatabase const& x)
433     {
434         if (m_pSelf)
435             Release();
436 
437         Clone(x);
438         return *this;
439     }
440 
Release()441     void CVDatabase::Release()
442     {
443         if (m_pSelf)
444         {
445 #if DEBUG_PRINT != 0
446             printf("Releasing VDatabase %p\n", m_pSelf);
447 #endif
448             ::VDatabaseRelease(m_pSelf);
449             m_pSelf = NULL;
450         }
451     }
452 
Clone(CVDatabase const & x)453     void CVDatabase::Clone(CVDatabase const& x)
454     {
455         m_pSelf = x.m_pSelf;
456         ::VDatabaseAddRef ( m_pSelf );
457 #if DEBUG_PRINT != 0
458         printf ("CLONING VDatabase %p\n", m_pSelf);
459 #endif
460     }
461 
OpenTable(char const * pszTableName) const462     CVTable CVDatabase::OpenTable(char const* pszTableName) const
463     {
464         CVTable table;
465         rc_t rc = ::VDatabaseOpenTableRead(m_pSelf, const_cast<VTable const**>(& table.m_pSelf), pszTableName);
466         if (rc)
467             throw Utils::CErrorMsg(rc, "VDatabaseOpenTableRead (%s)", pszTableName);
468 
469 #if DEBUG_PRINT != 0
470         printf("Opened table %p (%s)\n", table.m_pSelf, pszTableName);
471 #endif
472         return table;
473     }
474 
CreateTable(char const * pszTableName)475     CVTable CVDatabase::CreateTable ( char const* pszTableName )
476     {
477         CVTable table;
478         //rc_t rc = ::VDatabaseCreateTableDefault ( m_pSelf, & table.m_pSelf, pszTableName, pszTableName );
479         rc_t rc = ::VDatabaseCreateTableByMask ( m_pSelf, & table.m_pSelf, pszTableName, 0, 0, pszTableName );
480         if (rc)
481             throw Utils::CErrorMsg(rc, "VDatabaseCreateTableDefault (%s)", pszTableName);
482 
483 #if DEBUG_PRINT != 0
484         printf("Created table %p (%s)\n", table.m_pSelf, pszTableName);
485 #endif
486         return table;
487     }
488 
ColumnCreateParams(::KCreateMode cmode,::KChecksum checksum,size_t pgsize)489     void CVDatabase::ColumnCreateParams ( ::KCreateMode cmode, ::KChecksum checksum, size_t pgsize )
490     {
491         rc_t rc = ::VDatabaseColumnCreateParams ( m_pSelf, cmode, checksum, pgsize );
492         if (rc)
493             throw Utils::CErrorMsg(rc, "VDatabaseColumnCreateParams");
494     }
495 
496 //////////////////////////////////////////////////////////////////////
497 
CVSchema()498     CVSchema::CVSchema() : m_pSelf (NULL)
499     {
500     }
~CVSchema()501     CVSchema::~CVSchema()
502     {
503         Release();
504     }
505 
CVSchema(CVSchema const & x)506     CVSchema::CVSchema(CVSchema const& x)
507     {
508         Clone (x);
509     }
510 
operator =(CVSchema const & x)511     CVSchema& CVSchema::operator=(CVSchema const& x)
512     {
513         Clone (x);
514         return *this;
515     }
516 
Release()517     void CVSchema::Release()
518     {
519         if (m_pSelf)
520         {
521 #if DEBUG_PRINT != 0
522             printf("Releasing VSchema %p\n", m_pSelf);
523 #endif
524             ::VSchemaRelease ( m_pSelf );
525             m_pSelf = NULL;
526         }
527     }
528 
Clone(CVSchema const & x)529     void CVSchema::Clone ( CVSchema const& x )
530     {
531         if (false && m_pSelf)
532         {
533             assert(0);
534             Release();
535         }
536         m_pSelf = x.m_pSelf;
537         ::VSchemaAddRef ( m_pSelf );
538 #if DEBUG_PRINT != 0
539         printf ("CLONING VSchema %p\n", m_pSelf);
540 #endif
541     }
542 
VSchemaParseFile(char const * pszFilePath)543     void CVSchema::VSchemaParseFile ( char const* pszFilePath )
544     {
545         rc_t rc = ::VSchemaParseFile ( m_pSelf, pszFilePath );
546         if (rc)
547             throw Utils::CErrorMsg(rc, "VSchemaParseFile (%s)", pszFilePath);
548     }
549 
550 //////////////////////////////////////////////////////////////////////
551 
CVDBManager()552     CVDBManager::CVDBManager() : m_pSelf(NULL)
553     {}
554 
~CVDBManager()555     CVDBManager::~CVDBManager()
556     {
557         Release();
558     }
559 
Release()560     void CVDBManager::Release()
561     {
562         if (m_pSelf)
563         {
564 #if DEBUG_PRINT != 0
565             printf("Releasing VDBManager %p\n", m_pSelf);
566 #endif
567             ::VDBManagerRelease(m_pSelf);
568             m_pSelf = NULL;
569         }
570     }
571 
572 #if MANAGER_WRITABLE != 0
Make()573     void CVDBManager::Make()
574     {
575         assert(m_pSelf == NULL);
576         if (m_pSelf)
577             throw Utils::CErrorMsg(0, "Double call to VDBManagerMakeUpdate");
578 
579         rc_t rc = ::VDBManagerMakeUpdate ( & m_pSelf, NULL );
580         if (rc)
581             throw Utils::CErrorMsg(rc, "VDBManagerMakeUpdate");
582 
583 	    /*rc = VDBManagerDisablePagemapThread ( m_pSelf );
584         if (rc)
585             throw Utils::CErrorMsg(rc, "VDBManagerDisablePagemapThread");*/
586 
587 #if DEBUG_PRINT != 0
588         printf("Created VDBManager (wr) %p\n", m_pSelf);
589 #endif
590     }
591 #else
Make()592     void CVDBManager::Make()
593     {
594         assert(m_pSelf == NULL);
595         if (m_pSelf)
596             throw Utils::CErrorMsg(0, "Double call to VDBManagerMakeRead");
597 
598         rc_t rc = ::VDBManagerMakeRead(const_cast<VDBManager const**>(&m_pSelf), NULL);
599         if (rc)
600             throw Utils::CErrorMsg(rc, "VDBManagerMakeRead");
601 
602 #if DEBUG_PRINT != 0
603         printf("Created VDBManager (rd) %p\n", m_pSelf);
604 #endif
605     }
606 #endif
607 
OpenDB(char const * pszDBName) const608     CVDatabase CVDBManager::OpenDB(char const* pszDBName) const
609     {
610         CVDatabase vdb;
611         rc_t rc = ::VDBManagerOpenDBRead(m_pSelf, const_cast<VDatabase const**>(& vdb.m_pSelf), NULL, pszDBName);
612         if (rc)
613             throw Utils::CErrorMsg(rc, "VDBManagerOpenDBRead (%s)", pszDBName);
614 
615 #if DEBUG_PRINT != 0
616         printf("Opened database %p (%s)\n", vdb.m_pSelf, pszDBName);
617 #endif
618         return vdb;
619     }
620 #if MANAGER_WRITABLE != 0
CreateDB(CVSchema const & schema,char const * pszTypeDesc,::KCreateMode cmode,char const * pszPath)621     CVDatabase CVDBManager::CreateDB ( CVSchema const& schema, char const* pszTypeDesc, ::KCreateMode cmode, char const* pszPath )
622     {
623         CVDatabase vdb;
624         rc_t rc = ::VDBManagerCreateDB ( m_pSelf, & vdb.m_pSelf, schema.m_pSelf, pszTypeDesc, cmode, pszPath );
625         if (rc)
626             throw Utils::CErrorMsg(rc, "VDBManagerCreateDB (%s)", pszPath);
627 
628 #if DEBUG_PRINT != 0
629         printf("Created database %p (%s)\n", vdb.m_pSelf, pszPath);
630 #endif
631         // set creation mode of objects ( tables, columns, etc. ) to
632         // create new or re-initialize existing, plus attach md5 checksums
633         // to all files.
634         // set blob creation mode to record 32-bit CRC within blob
635         // continue to use default page size...
636         vdb.ColumnCreateParams ( kcmInit | kcmMD5, kcsCRC32, 0 );
637         return vdb;
638     }
639 #endif
640 
MakeSchema() const641     CVSchema CVDBManager::MakeSchema () const
642     {
643         CVSchema schema;
644         rc_t rc = ::VDBManagerMakeSchema ( m_pSelf, & schema.m_pSelf );
645         if (rc)
646             throw Utils::CErrorMsg(rc, "VDBManagerMakeSchema");
647 
648 #if DEBUG_PRINT != 0
649         printf("Created Schema %p\n", schema.m_pSelf);
650 #endif
651         return schema;
652     }
653 }
654 
655 namespace KApp
656 {
CArgs(int argc,char ** argv,::OptDef const * pOptions,size_t option_count)657     CArgs::CArgs (int argc, char** argv, ::OptDef const* pOptions, size_t option_count)
658         : m_pSelf(NULL)
659     {
660         MakeAndHandle ( argc, argv, pOptions, option_count );
661     }
662 
CArgs(int argc,char ** argv,::OptDef const * pOptions1,size_t option_count1,::OptDef const * pOptions2,size_t option_count2)663     CArgs::CArgs (int argc, char** argv, ::OptDef const* pOptions1, size_t option_count1, ::OptDef const* pOptions2, size_t option_count2)
664         : m_pSelf(NULL)
665     {
666         MakeAndHandle ( argc, argv, pOptions1, option_count1, pOptions2, option_count2 );
667     }
668 
~CArgs()669     CArgs::~CArgs()
670     {
671         Release();
672     }
673 
MakeAndHandle(int argc,char ** argv,::OptDef const * pOptions,size_t option_count)674     void CArgs::MakeAndHandle (int argc, char** argv, ::OptDef const* pOptions, size_t option_count)
675     {
676         if (m_pSelf)
677             throw Utils::CErrorMsg (0, "Duplicated call to ArgsMakeAndHandle");
678 
679         rc_t rc = ::ArgsMakeAndHandle (&m_pSelf, argc, argv, 1, pOptions, option_count);
680         if (rc)
681             throw Utils::CErrorMsg(rc, "ArgsMakeAndHandle");
682 #if DEBUG_PRINT != 0
683         printf("Created Args %p\n", m_pSelf);
684 #endif
685     }
MakeAndHandle(int argc,char ** argv,::OptDef const * pOptions1,size_t option_count1,::OptDef const * pOptions2,size_t option_count2)686     void CArgs::MakeAndHandle ( int argc, char** argv, ::OptDef const* pOptions1, size_t option_count1, ::OptDef const* pOptions2, size_t option_count2 )
687     {
688         if (m_pSelf)
689             throw Utils::CErrorMsg (0, "Duplicated call to ArgsMakeAndHandle");
690 
691         rc_t rc = ::ArgsMakeAndHandle (&m_pSelf, argc, argv, 2, pOptions1, option_count1, pOptions2, option_count2);
692         if (rc)
693             throw Utils::CErrorMsg(rc, "ArgsMakeAndHandle(2)");
694 #if DEBUG_PRINT != 0
695         printf("Created Args(2) %p\n", m_pSelf);
696 #endif
697     }
698 
Release()699     void CArgs::Release()
700     {
701         if (m_pSelf)
702         {
703 #if DEBUG_PRINT != 0
704             printf("Releasing Args %p\n", m_pSelf);
705 #endif
706             ::ArgsRelease (m_pSelf);
707             m_pSelf = NULL;
708         }
709     }
710 
GetArgs() const711     ::Args const* CArgs::GetArgs () const
712     {
713         return m_pSelf;
714     }
715 
GetParamCount() const716     uint32_t CArgs::GetParamCount () const
717     {
718         uint32_t ret = 0;
719         rc_t rc = ::ArgsParamCount ( m_pSelf, &ret );
720         if (rc)
721             throw Utils::CErrorMsg(rc, "ArgsParamCount");
722 
723         return ret;
724     }
725 
GetParamValue(uint32_t iteration) const726     char const* CArgs::GetParamValue ( uint32_t iteration ) const
727     {
728         void const* ret = NULL;
729         rc_t rc = ::ArgsParamValue ( m_pSelf, iteration, & ret );
730         if (rc)
731             throw Utils::CErrorMsg(rc, "ArgsParamValue");
732 
733         return static_cast <char const*> (ret);
734     }
735 
GetOptionCount(char const * option_name) const736     uint32_t CArgs::GetOptionCount ( char const* option_name ) const
737     {
738         uint32_t ret = 0;
739         rc_t rc = ::ArgsOptionCount ( m_pSelf, option_name, &ret );
740         if (rc)
741             throw Utils::CErrorMsg(rc, "ArgsOptionCount (%s)", option_name);
742 
743         return ret;
744     }
745 
GetOptionValue(char const * option_name,uint32_t iteration) const746     char const* CArgs::GetOptionValue ( char const* option_name, uint32_t iteration ) const
747     {
748         void const* ret = NULL;
749         rc_t rc = ::ArgsOptionValue ( m_pSelf, option_name, iteration, & ret );
750         if (rc)
751             throw Utils::CErrorMsg(rc, "ArgsOptionValue (%s)", option_name);
752 
753         return static_cast <char const*> (ret);
754     }
755 
756 ////////////////////////////////
757 
CProgressBar(uint64_t size)758     CProgressBar::CProgressBar ( uint64_t size )
759     {
760         Make ( size );
761     }
762 
~CProgressBar()763     CProgressBar::~CProgressBar ()
764     {
765         Release ();
766     }
767 
Make(uint64_t size)768     void CProgressBar::Make ( uint64_t size )
769     {
770         rc_t rc = ::KLoadProgressbar_Make ( &m_pSelf, size );
771         if (rc)
772             throw Utils::CErrorMsg(rc, "KLoadProgressbar_Make");
773 #if DEBUG_PRINT != 0
774         printf ( "Created ProgressBar %p\n", m_pSelf );
775 #endif
776     }
Release()777     void CProgressBar::Release ()
778     {
779         if (m_pSelf)
780         {
781 #if DEBUG_PRINT != 0
782             printf("Releasing ProgressBar %p\n", m_pSelf);
783 #endif
784             ::KLoadProgressbar_Release ( m_pSelf, true );
785             m_pSelf = NULL;
786         }
787     }
788 
Append(uint64_t chunk)789     void CProgressBar::Append ( uint64_t chunk )
790     {
791         rc_t rc = ::KLoadProgressbar_Append ( m_pSelf, chunk );
792         if (rc)
793             throw Utils::CErrorMsg(rc, "KLoadProgressbar_Append");
794     }
795 
Process(uint64_t chunk,bool force_report)796     void CProgressBar::Process ( uint64_t chunk, bool force_report )
797     {
798         rc_t rc = ::KLoadProgressbar_Process ( m_pSelf, chunk, force_report );
799         if (rc)
800             throw Utils::CErrorMsg(rc, "KLoadProgressbar_Process");
801     }
802 
803 ///////////////////////////////////////////
CXMLLogger(CArgs const & args)804     CXMLLogger::CXMLLogger ( CArgs const& args )
805     {
806         Make ( args );
807     }
808 
~CXMLLogger()809     CXMLLogger::~CXMLLogger ()
810     {
811         Release ();
812     }
813 
Make(CArgs const & args)814     void CXMLLogger::Make ( CArgs const& args )
815     {
816         rc_t rc = ::XMLLogger_Make ( &m_pSelf, NULL, args.m_pSelf );
817         if (rc)
818             throw Utils::CErrorMsg(rc, "XMLLogger_Make");
819 #if DEBUG_PRINT != 0
820         printf ( "Created XMLLogger %p\n", m_pSelf );
821 #endif
822     }
823 
Release()824     void CXMLLogger::Release ()
825     {
826         if (m_pSelf)
827         {
828 #if DEBUG_PRINT != 0
829             printf("Releasing XMLLogger %p\n", m_pSelf);
830 #endif
831             ::XMLLogger_Release ( m_pSelf );
832             m_pSelf = NULL;
833         }
834     }
835 }
836 
837 namespace Utils
838 {
CErrorMsg(rc_t rc,char const * fmt_str,...)839     CErrorMsg::CErrorMsg(rc_t rc, char const* fmt_str, ...)
840         : m_rc(rc)
841     {
842         va_list args;
843         va_start(args, fmt_str);
844         string_vprintf (m_szDescr, countof(m_szDescr), NULL, fmt_str, args);
845         va_end(args);
846     }
847 
getRC() const848     rc_t CErrorMsg::getRC() const
849     {
850         return m_rc;
851     }
what() const852     char const* CErrorMsg::what() const throw()
853     {
854         return m_szDescr;
855     }
856 
HandleException(bool bSilent,char * pErrDesc,size_t sizeErrDesc)857     int64_t HandleException ( bool bSilent, char* pErrDesc, size_t sizeErrDesc )
858     {
859         try
860         {
861             throw;
862         }
863         catch (Utils::CErrorMsg const& e)
864         {
865             char szBufErr[512];
866             if ( pErrDesc == NULL )
867             {
868                 pErrDesc = szBufErr;
869                 sizeErrDesc = countof(szBufErr);
870             }
871             size_t rc = e.getRC();
872             rc_t res;
873             if (rc != 0)
874                 res = string_printf(pErrDesc, sizeErrDesc, NULL, "%s failed with code 0x%08x (%u) [%R]", e.what(), rc, rc, rc);
875             else
876                 res = string_printf(pErrDesc, sizeErrDesc, NULL, "%s", e.what());
877             if (res == rcBuffer || res == rcInsufficient)
878                 pErrDesc [sizeErrDesc - 1] = '\0';
879 
880             if ( ! bSilent )
881                 LOGMSG ( klogErr, pErrDesc );
882 
883             return rc;
884         }
885         catch (std::exception const& e)
886         {
887             char szBufErr[512];
888             if ( pErrDesc == NULL )
889             {
890                 pErrDesc = szBufErr;
891                 sizeErrDesc = countof(szBufErr);
892             }
893             rc_t res = string_printf(pErrDesc, sizeErrDesc, NULL, "std::exception: %s", e.what());
894             if (res == rcBuffer || res == rcInsufficient)
895                 pErrDesc [sizeErrDesc - 1] = '\0';
896 
897             if ( ! bSilent )
898                 LOGMSG ( klogErr, pErrDesc );
899 
900             return Utils::rcErrorStdExc;
901         }
902         catch (...)
903         {
904             char szBufErr[512];
905             if ( pErrDesc == NULL )
906             {
907                 pErrDesc = szBufErr;
908                 sizeErrDesc = countof(szBufErr);
909             }
910             rc_t res = string_printf(pErrDesc, sizeErrDesc, NULL, "Unexpected exception occured");
911             if (res == rcBuffer || res == rcInsufficient)
912                 pErrDesc [sizeErrDesc - 1] = '\0';
913 
914             if ( ! bSilent )
915                 LOGMSG ( klogErr, pErrDesc );
916 
917             return Utils::rcUnknown;
918         }
919 
920         assert ( false );
921         return Utils::rcInvalid; // this shall never be reached
922     }
923 }
924