00001 #ifndef BDB_TYPES__HPP
00002 #define BDB_TYPES__HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <db/bdb/bdb_expt.hpp>
00036 #include <corelib/ncbi_limits.hpp>
00037 #include <corelib/ncbi_bswap.hpp>
00038 #include <corelib/ncbistr.hpp>
00039 #include <util/simple_buffer.hpp>
00040
00041 #include <string>
00042 #include <vector>
00043 #include <memory>
00044
00045
00046 extern "C" {
00047
00048
00049
00050
00051 struct __db_dbt; typedef struct __db_dbt DBT;
00052 struct __db; typedef struct __db DB;
00053 struct __dbc; typedef struct __dbc DBC;
00054 struct __db_env; typedef struct __db_env DB_ENV;
00055 struct __db_txn; typedef struct __db_txn DB_TXN;
00056
00057 typedef int (*BDB_CompareFunction)(DB*, const DBT*, const DBT*);
00058 typedef unsigned int (*BDB_HashFunction)
00059 (DB *, const void *bytes, unsigned length);
00060 }
00061
00062 BEGIN_NCBI_SCOPE
00063
00064
00065
00066
00067
00068
00069
00070 extern "C" {
00071
00072
00073
00074
00075 NCBI_DEPRECATED
00076 int BDB_UintCompare(DB*, const DBT* val1, const DBT* val2);
00077 int BDB_Uint4Compare(DB*, const DBT* val1, const DBT* val2);
00078
00079
00080
00081 NCBI_DEPRECATED
00082 int BDB_IntCompare(DB*, const DBT* val1, const DBT* val2);
00083 int BDB_Int4Compare(DB*, const DBT* val1, const DBT* val2);
00084
00085
00086
00087 int BDB_Int8Compare(DB*, const DBT* val1, const DBT* val2);
00088
00089
00090
00091 int BDB_Uint8Compare(DB*, const DBT* val1, const DBT* val2);
00092
00093
00094
00095 int BDB_Int2Compare(DB*, const DBT* val1, const DBT* val2);
00096
00097
00098
00099 int BDB_Uint2Compare(DB*, const DBT* val1, const DBT* val2);
00100
00101
00102
00103 int BDB_CharCompare(DB*, const DBT* val1, const DBT* val2);
00104
00105
00106
00107 int BDB_UCharCompare(DB*, const DBT* val1, const DBT* val2);
00108
00109
00110
00111 int BDB_FloatCompare(DB*, const DBT* val1, const DBT* val2);
00112
00113
00114
00115 int BDB_DoubleCompare(DB*, const DBT* val1, const DBT* val2);
00116
00117
00118
00119 int BDB_StringCompare(DB*, const DBT* val1, const DBT* val2);
00120
00121
00122
00123 int BDB_LStringCompare(DB*, const DBT* val1, const DBT* val2);
00124
00125
00126
00127 int BDB_FixedByteStringCompare
00128 (DB*, const DBT* val1, const DBT* val2);
00129
00130
00131
00132
00133 int
00134 BDB_StringCaseCompare(DB*, const DBT* val1, const DBT* val2);
00135
00136
00137 int BDB_Compare(DB* db, const DBT* val1, const DBT* val2);
00138
00139
00140
00141
00142
00143
00144 NCBI_DEPRECATED
00145 int
00146 BDB_ByteSwap_UintCompare(DB*, const DBT* val1, const DBT* val2);
00147 int
00148 BDB_ByteSwap_Uint4Compare(DB*, const DBT* val1, const DBT* val2);
00149
00150
00151
00152
00153 int
00154 BDB_ByteSwap_Int8Compare(DB*, const DBT* val1, const DBT* val2);
00155
00156
00157
00158
00159 int
00160 BDB_ByteSwap_Uint8Compare(DB*, const DBT* val1, const DBT* val2);
00161
00162
00163
00164
00165 NCBI_DEPRECATED
00166 int
00167 BDB_ByteSwap_IntCompare(DB*, const DBT* val1, const DBT* val2);
00168 int
00169 BDB_ByteSwap_Int4Compare(DB*, const DBT* val1, const DBT* val2);
00170
00171
00172
00173
00174 int
00175 BDB_ByteSwap_Int2Compare(DB*, const DBT* val1, const DBT* val2);
00176
00177
00178
00179
00180 int
00181 BDB_ByteSwap_Uint2Compare(DB*, const DBT* val1, const DBT* val2);
00182
00183
00184
00185
00186 int
00187 BDB_ByteSwap_FloatCompare(DB*, const DBT* val1, const DBT* val2);
00188
00189
00190
00191
00192 int
00193 BDB_ByteSwap_DoubleCompare(DB*, const DBT* val1, const DBT* val2);
00194
00195
00196
00197 unsigned int
00198 BDB_Hash(DB *, const void *bytes, unsigned length);
00199
00200
00201 unsigned int
00202 BDB_Uint4Hash(DB *, const void *bytes, unsigned length);
00203
00204
00205 }
00206
00207
00208 class CBDB_BufferManager;
00209 class CBDB_Field;
00210 class CBDB_File;
00211 class CBDB_FileCursor;
00212 class CBDB_FC_Condition;
00213
00214
00215
00216
00217
00218
00219
00220
00221 class IBDB_Field
00222 {
00223 public:
00224 virtual ~IBDB_Field();
00225
00226
00227
00228
00229
00230
00231 virtual int Compare(const void* p1,
00232 const void* p2,
00233 bool byte_swapped) const = 0;
00234
00235
00236 virtual size_t GetDataLength(const void* buf) const = 0;
00237
00238
00239 virtual void SetMinVal() = 0;
00240
00241
00242 virtual void SetMaxVal() = 0;
00243 };
00244
00245
00246
00247
00248
00249
00250 class IBDB_FieldConvert
00251 {
00252 public:
00253 virtual ~IBDB_FieldConvert() {}
00254
00255 virtual void SetInt(int)
00256 { BDB_THROW(eType, "Bad conversion"); }
00257 virtual void SetUint(unsigned)
00258 { BDB_THROW(eType, "Bad conversion"); }
00259 virtual int GetInt() const
00260 { BDB_THROW(eType, "Bad conversion"); }
00261 virtual unsigned GetUint() const
00262 { BDB_THROW(eType, "Bad conversion"); }
00263 virtual void SetString(const char*)
00264 { BDB_THROW(eType, "Bad conversion"); }
00265 virtual void SetStdString(const string&)
00266 { BDB_THROW(eType, "Bad conversion"); }
00267 virtual void SetFloat(float)
00268 { BDB_THROW(eType, "Bad conversion"); }
00269 virtual void SetDouble(double)
00270 { BDB_THROW(eType, "Bad conversion"); }
00271
00272 virtual string GetString() const = 0;
00273
00274 virtual void ToString(string& str) const = 0;
00275 };
00276
00277
00278
00279
00280
00281
00282 class CBDB_FieldInterfaces : public IBDB_Field,
00283 public IBDB_FieldConvert
00284 {
00285 friend class CBDB_FileCursor;
00286 };
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 class CBDB_Field : public CBDB_FieldInterfaces
00297 {
00298 public:
00299
00300 enum ELengthType {
00301 eFixedLength,
00302 eVariableLength
00303 };
00304 CBDB_Field(ELengthType length_type = eFixedLength);
00305 virtual ~CBDB_Field() {}
00306
00307
00308
00309
00310 virtual CBDB_Field* Construct(size_t buf_size = 0) const = 0;
00311
00312
00313
00314 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const;
00315
00316
00317 bool IsNullable() const;
00318
00319
00320 void SetNull();
00321
00322
00323 bool IsNull() const;
00324
00325
00326 const string& GetName() const;
00327
00328
00329 const void* GetBuffer() const;
00330
00331 void* GetBuffer();
00332
00333
00334 size_t GetBufferSize() const;
00335
00336
00337 size_t GetLength() const;
00338
00339 protected:
00340
00341
00342 int CompareWith(const CBDB_Field& field) const;
00343
00344
00345
00346 void CopyFrom(const CBDB_Field& src);
00347
00348
00349
00350
00351 bool IsVariableLength() const;
00352
00353
00354 bool IsBufferAttached() const;
00355
00356
00357 bool IsSameType(const CBDB_Field& field) const;
00358
00359
00360
00361 bool IsByteSwapped() const;
00362
00363
00364
00365 void SetNullable();
00366
00367
00368 void SetNotNull();
00369
00370
00371 void SetName(const char* name);
00372
00373
00374 void SetBufferIdx(unsigned int idx);
00375
00376
00377 protected:
00378
00379
00380 void* Unpack();
00381
00382
00383 void SetBuffer(void* buf, size_t buf_size = 0);
00384
00385 void SetBufferSize(size_t size);
00386
00387 void SetDataSize(size_t size);
00388
00389 virtual size_t GetExtraDataLength();
00390
00391 void SetBufferManager(CBDB_BufferManager* owner);
00392
00393
00394 void CopyFrom(const void* src_buf);
00395
00396 private:
00397 CBDB_Field& operator= (const CBDB_Field& data);
00398 CBDB_Field(const CBDB_Field& data);
00399
00400 protected:
00401 CBDB_BufferManager* m_BufferManager;
00402 struct {
00403 unsigned VariableLength : 1;
00404 unsigned Attached : 1;
00405 unsigned Nullable : 1;
00406 } m_Flags;
00407 private:
00408 void* m_Buffer;
00409 size_t m_BufferSize;
00410 unsigned m_BufferIdx;
00411 string m_Name;
00412
00413
00414 friend class CBDB_BufferManager;
00415 friend class CBDB_File;
00416 friend class CBDB_BLobFile;
00417 };
00418
00419
00420
00421
00422
00423
00424 template<typename T>
00425 class CBDB_FieldSimple : public CBDB_Field
00426 {
00427 public:
00428 typedef T TFieldType;
00429 public:
00430 CBDB_FieldSimple()
00431 : CBDB_Field(eFixedLength)
00432 {
00433 SetBufferSize(sizeof(T));
00434 }
00435
00436 void SetField(const CBDB_FieldSimple& field)
00437 {
00438 if ( field.IsNull() ) {
00439 SetNull();
00440 } else {
00441 if (IsByteSwapped() != field.IsByteSwapped()) {
00442 BDB_THROW(eInvalidValue, "Byte order incompatibility");
00443 }
00444 #ifdef HAVE_UNALIGNED_READS
00445 TFieldType* b = (TFieldType*) GetBuffer();
00446 TFieldType* f = (TFieldType*) field.GetBuffer();
00447 *b = *f;
00448 #else
00449 ::memcpy(GetBuffer(), field.GetBuffer(), sizeof(T));
00450 #endif
00451 SetNotNull();
00452 }
00453 }
00454
00455
00456
00457 virtual int Compare(const void* p1,
00458 const void* p2,
00459 bool) const
00460 {
00461
00462 T v1, v2;
00463
00464 #ifdef HAVE_UNALIGNED_READS
00465 v1 = *((TFieldType*)p1);
00466 v2 = *((TFieldType*)p2);
00467 #else
00468 ::memcpy(&v1, p1, sizeof(v1));
00469 ::memcpy(&v2, p2, sizeof(v2));
00470 #endif
00471 if (v1 < v2) return -1;
00472 if (v2 < v1) return 1;
00473 return 0;
00474 }
00475
00476 virtual size_t GetDataLength(const void* ) const
00477 {
00478 return sizeof(T);
00479 }
00480 };
00481
00482
00483
00484
00485
00486
00487 template<typename T>
00488 class CBDB_FieldSimpleInt : public CBDB_FieldSimple<T>
00489 {
00490 public:
00491 CBDB_FieldSimpleInt() : CBDB_FieldSimple<T>() {}
00492
00493 void Set(T val)
00494 {
00495 if (this->IsByteSwapped()) {
00496
00497 if (sizeof(T) == 2) {
00498 CByteSwap::PutInt2((unsigned char*)this->GetBuffer(),
00499 (Int2) val);
00500 } else
00501 if (sizeof(T) == 4) {
00502 CByteSwap::PutInt4((unsigned char*)this->GetBuffer(),
00503 (Int4) val);
00504 } else
00505 if (sizeof(T) == 8) {
00506 CByteSwap::PutInt8((unsigned char*)this->GetBuffer(),
00507 (Int8) val);
00508 }
00509 else {
00510 _ASSERT(0);
00511 }
00512
00513 } else {
00514 #ifdef HAVE_UNALIGNED_READS
00515 typename CBDB_FieldSimple<T>::TFieldType* b =
00516 (typename CBDB_FieldSimple<T>::TFieldType*) this->GetBuffer();
00517 *b = val;
00518 #else
00519 ::memcpy(this->GetBuffer(), &val, sizeof(T));
00520 #endif
00521 }
00522 this->SetNotNull();
00523 }
00524
00525 virtual void SetInt (int val) { Set((T) val); }
00526 virtual void SetUint (unsigned int val) { Set((T) val); }
00527 virtual void SetString (const char* val)
00528 {
00529 long v = ::atol(val);
00530 Set((T) v);
00531 }
00532
00533 virtual int GetInt() const
00534 {
00535 int value;
00536 #ifdef HAVE_UNALIGNED_READS
00537 typename CBDB_FieldSimple<T>::TFieldType* b =
00538 (typename CBDB_FieldSimple<T>::TFieldType*) this->GetBuffer();
00539 value = (int)*b;
00540 #else
00541 ::memcpy(&value, this->GetBuffer(), sizeof(T));
00542 #endif
00543 return value;
00544 }
00545
00546 virtual unsigned GetUint() const
00547 {
00548 unsigned value;
00549 #ifdef HAVE_UNALIGNED_READS
00550 typename CBDB_FieldSimple<T>::TFieldType* b =
00551 (typename CBDB_FieldSimple<T>::TFieldType*) this->GetBuffer();
00552 value = (unsigned)*b;
00553 #else
00554 ::memcpy(&value, this->GetBuffer(), sizeof(T));
00555 #endif
00556 return value;
00557 }
00558
00559 virtual void SetStdString(const string& str)
00560 {
00561 SetString(str.c_str());
00562 }
00563
00564 virtual int Compare(const void* p1,
00565 const void* p2,
00566 bool byte_swapped) const
00567 {
00568 if (!byte_swapped)
00569 return CBDB_FieldSimple<T>::Compare(p1, p2, byte_swapped);
00570
00571 T v1, v2;
00572 v1 = (T) CByteSwap::GetInt4((unsigned char*)p1);
00573 v2 = (T) CByteSwap::GetInt4((unsigned char*)p2);
00574 if (v1 < v2) return -1;
00575 if (v2 < v1) return 1;
00576 return 0;
00577 }
00578
00579 virtual void SetMinVal()
00580 {
00581 Set(numeric_limits<T>::min());
00582 }
00583
00584 virtual void SetMaxVal()
00585 {
00586 Set(numeric_limits<T>::max());
00587 }
00588 };
00589
00590
00591
00592
00593
00594
00595
00596 template<typename T>
00597 class CBDB_FieldSimpleFloat : public CBDB_FieldSimple<T>
00598 {
00599 public:
00600 CBDB_FieldSimpleFloat() : CBDB_FieldSimple<T>() {}
00601
00602 void Set(T val)
00603 {
00604 if (this->IsByteSwapped()) {
00605
00606 if (sizeof(T) == 4) {
00607 CByteSwap::PutFloat((unsigned char*)this->GetBuffer(),
00608 (float)val);
00609 } else
00610 if (sizeof(T) == 8) {
00611 CByteSwap::PutDouble((unsigned char*)this->GetBuffer(), val);
00612 }
00613 else {
00614 _ASSERT(0);
00615 }
00616 } else {
00617 #ifdef HAVE_UNALIGNED_READS
00618 typename CBDB_FieldSimple<T>::TFieldType* b =
00619 (typename CBDB_FieldSimple<T>::TFieldType*) this->GetBuffer();
00620 *b = val;
00621 #else
00622 ::memcpy(this->GetBuffer(), &val, sizeof(T));
00623 #endif
00624 }
00625 this->SetNotNull();
00626 }
00627
00628 virtual void SetInt (int val) { Set((T) val); }
00629 virtual void SetUint (unsigned int val) { Set((T) val); }
00630 virtual void SetString (const char* val)
00631 {
00632 double v = ::atof(val);
00633 Set((T) v);
00634 }
00635 virtual void SetStdString(const string& str)
00636 {
00637 SetString(str.c_str());
00638 }
00639
00640 virtual void SetFloat (float val) { Set((T) val); }
00641 virtual void SetDouble(double val) { Set((T) val); }
00642
00643 virtual void SetMinVal()
00644 {
00645 Set(numeric_limits<T>::min());
00646 }
00647
00648 virtual void SetMaxVal()
00649 {
00650 Set(numeric_limits<T>::max());
00651 }
00652 };
00653
00654
00655
00656
00657
00658 class CBDB_FieldInt8 : public CBDB_FieldSimpleInt<Int8>
00659 {
00660 public:
00661 CBDB_FieldInt8& operator= (Int8 val)
00662 {
00663 Set(val);
00664 return *this;
00665 }
00666
00667 CBDB_FieldInt8& operator= (const CBDB_FieldInt8& val)
00668 {
00669 Set(val);
00670 return *this;
00671 }
00672
00673 virtual CBDB_Field* Construct(size_t ) const
00674 {
00675 return new CBDB_FieldInt8();
00676 }
00677
00678 Int8 Get() const
00679 {
00680 Int8 v;
00681
00682 _ASSERT(!IsNull());
00683
00684 if (IsByteSwapped()) {
00685 v = CByteSwap::GetInt8((unsigned char*)GetBuffer());
00686 } else {
00687 #ifdef HAVE_UNALIGNED_READS
00688 TFieldType* b = (TFieldType*) this->GetBuffer();
00689 v = *b;
00690 #else
00691 ::memcpy(&v, GetBuffer(), sizeof(Int8));
00692 #endif
00693 }
00694 return v;
00695 }
00696
00697 virtual string GetString() const
00698 {
00699 Int8 v = Get();
00700 return NStr::Int8ToString(v);
00701 }
00702
00703 virtual void ToString(string& str) const
00704 {
00705 Int8 v = Get();
00706 NStr::Int8ToString(str, v);
00707 }
00708
00709 operator Int8() const
00710 {
00711 return Get();
00712 }
00713
00714 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
00715 {
00716 if (byte_swapped)
00717 return BDB_ByteSwap_Int8Compare;
00718 return BDB_Int8Compare;
00719 }
00720
00721 virtual int Compare(const void* p1,
00722 const void* p2,
00723 bool byte_swapped) const
00724 {
00725 if (!byte_swapped)
00726 return CBDB_FieldSimpleInt<Int8>::Compare(p1, p2, byte_swapped);
00727
00728 Int8 v1, v2;
00729 v1 = CByteSwap::GetInt8((unsigned char*)p1);
00730 v2 = CByteSwap::GetInt8((unsigned char*)p2);
00731 if (v1 < v2) return -1;
00732 if (v2 < v1) return 1;
00733 return 0;
00734 }
00735
00736 };
00737
00738
00739
00740
00741
00742 class CBDB_FieldUint8 : public CBDB_FieldSimpleInt<Uint8>
00743 {
00744 public:
00745 CBDB_FieldUint8& operator= (Uint8 val)
00746 {
00747 Set(val);
00748 return *this;
00749 }
00750
00751 CBDB_FieldUint8& operator= (const CBDB_FieldUint8& val)
00752 {
00753 Set(val);
00754 return *this;
00755 }
00756
00757 virtual CBDB_Field* Construct(size_t ) const
00758 {
00759 return new CBDB_FieldUint8();
00760 }
00761
00762 Uint8 Get() const
00763 {
00764 Uint8 v;
00765
00766 _ASSERT(!IsNull());
00767
00768 if (IsByteSwapped()) {
00769 v = CByteSwap::GetInt8((unsigned char*)GetBuffer());
00770 } else {
00771 #ifdef HAVE_UNALIGNED_READS
00772 TFieldType* b = (TFieldType*) GetBuffer();
00773 v = *b;
00774 #else
00775 ::memcpy(&v, GetBuffer(), sizeof(Uint8));
00776 #endif
00777 }
00778 return v;
00779 }
00780
00781 virtual string GetString() const
00782 {
00783 Uint8 v = Get();
00784 return NStr::UInt8ToString(v);
00785 }
00786
00787 virtual void ToString(string& str) const
00788 {
00789 Uint8 v = Get();
00790 NStr::UInt8ToString(str, v);
00791 }
00792
00793 operator Uint8() const
00794 {
00795 return Get();
00796 }
00797
00798 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
00799 {
00800 if (byte_swapped)
00801 return BDB_ByteSwap_Uint8Compare;
00802 return BDB_Uint8Compare;
00803 }
00804
00805 virtual int Compare(const void* p1,
00806 const void* p2,
00807 bool byte_swapped) const
00808 {
00809 if (!byte_swapped)
00810 return CBDB_FieldSimpleInt<Uint8>::Compare(p1, p2, byte_swapped);
00811
00812 Uint8 v1, v2;
00813 v1 = CByteSwap::GetInt8((unsigned char*)p1);
00814 v2 = CByteSwap::GetInt8((unsigned char*)p2);
00815 if (v1 < v2) return -1;
00816 if (v2 < v1) return 1;
00817 return 0;
00818 }
00819
00820 };
00821
00822
00823
00824
00825
00826 class CBDB_FieldInt4 : public CBDB_FieldSimpleInt<Int4>
00827 {
00828 public:
00829 CBDB_FieldInt4& operator= (Int4 val)
00830 {
00831 Set(val);
00832 return *this;
00833 }
00834
00835 CBDB_FieldInt4& operator= (const CBDB_FieldInt4& val)
00836 {
00837 Set(val);
00838 return *this;
00839 }
00840
00841 virtual CBDB_Field* Construct(size_t ) const
00842 {
00843 return new CBDB_FieldInt4();
00844 }
00845
00846 Int4 Get() const
00847 {
00848 Int4 v;
00849
00850 _ASSERT(!IsNull());
00851
00852 if (IsByteSwapped()) {
00853 v = CByteSwap::GetInt4((unsigned char*)GetBuffer());
00854 } else {
00855 #ifdef HAVE_UNALIGNED_READS
00856 TFieldType* b = (TFieldType*)GetBuffer();
00857 v = *b;
00858 #else
00859 ::memcpy(&v, GetBuffer(), sizeof(Int4));
00860 #endif
00861 }
00862 return v;
00863 }
00864
00865 virtual string GetString() const
00866 {
00867 Int4 v = Get();
00868 return NStr::IntToString(v);
00869 }
00870
00871 virtual void ToString(string& str) const
00872 {
00873 Int4 v = Get();
00874 NStr::IntToString(str, v);
00875 }
00876
00877 operator Int4() const
00878 {
00879 return Get();
00880 }
00881
00882 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
00883 {
00884 if (byte_swapped)
00885 return BDB_ByteSwap_Int4Compare;
00886 return BDB_Int4Compare;
00887 }
00888
00889 virtual int Compare(const void* p1,
00890 const void* p2,
00891 bool byte_swapped) const
00892 {
00893 if (!byte_swapped)
00894 return CBDB_FieldSimpleInt<Int4>::Compare(p1, p2, byte_swapped);
00895
00896 Int4 v1, v2;
00897 v1 = CByteSwap::GetInt4((unsigned char*)p1);
00898 v2 = CByteSwap::GetInt4((unsigned char*)p2);
00899 if (v1 < v2) return -1;
00900 if (v2 < v1) return 1;
00901 return 0;
00902 }
00903
00904 };
00905
00906
00907
00908
00909
00910 class CBDB_FieldInt2 : public CBDB_FieldSimpleInt<Int2>
00911 {
00912 public:
00913 CBDB_FieldInt2& operator= (Int2 val)
00914 {
00915 Set(val);
00916 return *this;
00917 }
00918
00919 CBDB_FieldInt2& operator= (const CBDB_FieldInt2& val)
00920 {
00921 Set(val);
00922 return *this;
00923 }
00924
00925 virtual CBDB_Field* Construct(size_t ) const
00926 {
00927 return new CBDB_FieldInt2();
00928 }
00929
00930 Int2 Get() const
00931 {
00932 Int2 v;
00933
00934 _ASSERT(!IsNull());
00935
00936 if (IsByteSwapped()) {
00937 v = CByteSwap::GetInt2((unsigned char*)GetBuffer());
00938 } else {
00939 #ifdef HAVE_UNALIGNED_READS
00940 TFieldType* b = (TFieldType*) GetBuffer();
00941 v = *b;
00942 #else
00943 ::memcpy(&v, GetBuffer(), sizeof(Int2));
00944 #endif
00945 }
00946 return v;
00947 }
00948
00949 virtual string GetString() const
00950 {
00951 Int4 v = Get();
00952 return NStr::IntToString(v);
00953 }
00954
00955 virtual void ToString(string& str) const
00956 {
00957 Int4 v = Get();
00958 NStr::IntToString(str, v);
00959 }
00960
00961 operator Int2() const
00962 {
00963 return Get();
00964 }
00965
00966 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
00967 {
00968 if (byte_swapped)
00969 return BDB_ByteSwap_Int2Compare;
00970 return BDB_Int2Compare;
00971 }
00972
00973 virtual int Compare(const void* p1,
00974 const void* p2,
00975 bool byte_swapped) const
00976 {
00977 if (!byte_swapped)
00978 return CBDB_FieldSimpleInt<Int2>::Compare(p1, p2, byte_swapped);
00979
00980 Int2 v1, v2;
00981 v1 = CByteSwap::GetInt2((unsigned char*)p1);
00982 v2 = CByteSwap::GetInt2((unsigned char*)p2);
00983 if (v1 < v2) return -1;
00984 if (v2 < v1) return 1;
00985 return 0;
00986 }
00987
00988 };
00989
00990
00991
00992
00993
00994 class CBDB_FieldUint2 : public CBDB_FieldSimpleInt<Uint2>
00995 {
00996 public:
00997 CBDB_FieldUint2& operator= (Uint2 val)
00998 {
00999 Set(val);
01000 return *this;
01001 }
01002
01003 CBDB_FieldUint2& operator= (const CBDB_FieldUint2& val)
01004 {
01005 Set(val);
01006 return *this;
01007 }
01008
01009 virtual CBDB_Field* Construct(size_t ) const
01010 {
01011 return new CBDB_FieldUint2();
01012 }
01013
01014 Uint2 Get() const
01015 {
01016 Uint2 v;
01017
01018 _ASSERT(!IsNull());
01019
01020 if (IsByteSwapped()) {
01021 v = CByteSwap::GetInt2((unsigned char*)GetBuffer());
01022 } else {
01023 #ifdef HAVE_UNALIGNED_READS
01024 TFieldType* b = (TFieldType*) GetBuffer();
01025 v = *b;
01026 #else
01027 ::memcpy(&v, GetBuffer(), sizeof(Uint2));
01028 #endif
01029 }
01030 return v;
01031 }
01032
01033 virtual string GetString() const
01034 {
01035 Int4 v = Get();
01036 return NStr::IntToString(v);
01037 }
01038
01039 virtual void ToString(string& str) const
01040 {
01041 Int4 v = Get();
01042 NStr::IntToString(str, v);
01043 }
01044
01045 operator Uint2() const
01046 {
01047 return Get();
01048 }
01049
01050 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
01051 {
01052 if (byte_swapped)
01053 return BDB_ByteSwap_Uint2Compare;
01054 return BDB_Uint2Compare;
01055 }
01056
01057 virtual int Compare(const void* p1,
01058 const void* p2,
01059 bool byte_swapped) const
01060 {
01061 if (!byte_swapped)
01062 return CBDB_FieldSimpleInt<Uint2>::Compare(p1, p2, byte_swapped);
01063
01064 Uint2 v1, v2;
01065 v1 = CByteSwap::GetInt2((unsigned char*)p1);
01066 v2 = CByteSwap::GetInt2((unsigned char*)p2);
01067 if (v1 < v2) return -1;
01068 if (v2 < v1) return 1;
01069 return 0;
01070 }
01071
01072 };
01073
01074
01075
01076
01077 class CBDB_FieldUChar : public CBDB_FieldSimpleInt<unsigned char>
01078 {
01079 public:
01080 CBDB_FieldUChar& operator = (unsigned char val)
01081 {
01082 Set(val);
01083 return *this;
01084 }
01085
01086 CBDB_FieldUChar& operator = (const CBDB_FieldUChar& val)
01087 {
01088 Set(val);
01089 return *this;
01090 }
01091
01092 virtual CBDB_Field * Construct(size_t) const
01093 {
01094 return new CBDB_FieldUChar();
01095 }
01096
01097 unsigned char Get() const
01098 {
01099 _ASSERT(!IsNull());
01100
01101 return *(const unsigned char*)GetBuffer();
01102 }
01103
01104 operator char () const
01105 {
01106 return Get();
01107 }
01108
01109 virtual string GetString() const
01110 {
01111 return string(1, Get());
01112 }
01113
01114 virtual void ToString(string& s) const
01115 {
01116 s.assign(1, Get());
01117 }
01118
01119 virtual BDB_CompareFunction GetCompareFunction(bool) const
01120 {
01121 return BDB_UCharCompare;
01122 }
01123
01124 virtual int Compare(const void * p1,
01125 const void * p2,
01126 bool) const
01127 {
01128 const unsigned char& c1 = *(const unsigned char *)p1;
01129 const unsigned char& c2 = *(const unsigned char *)p2;
01130
01131 return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0;
01132 }
01133 };
01134
01135 class CBDB_FieldChar : public CBDB_FieldSimpleInt<char>
01136 {
01137 public:
01138 CBDB_FieldChar& operator = (char val)
01139 {
01140 Set(val);
01141 return *this;
01142 }
01143
01144 CBDB_FieldChar& operator = (const CBDB_FieldChar& val)
01145 {
01146 Set(val);
01147 return *this;
01148 }
01149
01150 virtual CBDB_Field * Construct(size_t) const
01151 {
01152 return new CBDB_FieldChar();
01153 }
01154
01155 char Get() const
01156 {
01157 _ASSERT(!IsNull());
01158
01159 return *(const char*)GetBuffer();
01160 }
01161
01162 operator char () const
01163 {
01164 return Get();
01165 }
01166
01167 virtual string GetString() const
01168 {
01169 return string(1, Get());
01170 }
01171
01172 virtual void ToString(string& s) const
01173 {
01174 s.assign(1, Get());
01175 }
01176
01177 virtual BDB_CompareFunction GetCompareFunction(bool) const
01178 {
01179 return BDB_CharCompare;
01180 }
01181
01182 virtual int Compare(const void * p1,
01183 const void * p2,
01184 bool) const
01185 {
01186 const char& c1 = *(const char *)p1;
01187 const char& c2 = *(const char *)p2;
01188
01189 return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0;
01190 }
01191 };
01192
01193
01194
01195
01196 class CBDB_FieldInt1 : public CBDB_FieldChar
01197 {
01198 public:
01199 CBDB_FieldInt1& operator=(Int1 val)
01200 {
01201 Set(val);
01202 return *this;
01203 }
01204
01205 CBDB_FieldInt1& operator=(const CBDB_FieldChar& val)
01206 {
01207 Set(val);
01208 return *this;
01209 }
01210
01211 virtual CBDB_Field * Construct(size_t) const
01212 {
01213 return new CBDB_FieldInt1();
01214 }
01215
01216 virtual string GetString() const
01217 {
01218 return NStr::UIntToString(Get());
01219 }
01220
01221 virtual void ToString(string& s) const
01222 {
01223 s = GetString();
01224 }
01225 };
01226
01227
01228
01229
01230
01231 class CBDB_FieldUint1 : public CBDB_FieldUChar
01232 {
01233 public:
01234 CBDB_FieldUint1& operator= (unsigned char val)
01235 {
01236 Set(val);
01237 return *this;
01238 }
01239
01240 CBDB_FieldUint1& operator= (const CBDB_FieldUChar& val)
01241 {
01242 Set(val);
01243 return *this;
01244 }
01245
01246 virtual CBDB_Field * Construct(size_t) const
01247 {
01248 return new CBDB_FieldUint1();
01249 }
01250
01251 virtual string GetString() const
01252 {
01253 return NStr::UIntToString(Get());
01254 }
01255
01256 virtual void ToString(string& s) const
01257 {
01258 s = GetString();
01259 }
01260 };
01261
01262
01263
01264
01265
01266 class CBDB_FieldUint4 : public CBDB_FieldSimpleInt<Uint4>
01267 {
01268 public:
01269 CBDB_FieldUint4& operator= (Uint4 val)
01270 {
01271 Set(val);
01272 return *this;
01273 }
01274
01275 CBDB_FieldUint4& operator= (const CBDB_FieldUint4& val)
01276 {
01277 Set(val);
01278 return *this;
01279 }
01280
01281 virtual CBDB_Field* Construct(size_t ) const
01282 {
01283 return new CBDB_FieldUint4();
01284 }
01285
01286 Uint4 Get() const
01287 {
01288 Uint4 v;
01289
01290 _ASSERT(!IsNull());
01291
01292 if (IsByteSwapped()) {
01293 v = (Uint4)CByteSwap::GetInt4((unsigned char*)GetBuffer());
01294 } else {
01295 #ifdef HAVE_UNALIGNED_READS
01296 TFieldType* b = (TFieldType*) GetBuffer();
01297 v = *b;
01298 #else
01299 ::memcpy(&v, GetBuffer(), sizeof(Uint4));
01300 #endif
01301 }
01302 return v;
01303 }
01304
01305 virtual string GetString() const
01306 {
01307 Uint4 v = Get();
01308 return NStr::UIntToString(v);
01309 }
01310
01311 virtual void ToString(string& str) const
01312 {
01313 Uint4 v = Get();
01314 NStr::UIntToString(str, v);
01315 }
01316
01317 operator Uint4() const
01318 {
01319 return Get();
01320 }
01321
01322 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
01323 {
01324 if (byte_swapped)
01325 return BDB_ByteSwap_Uint4Compare;
01326 return BDB_Uint4Compare;
01327 }
01328
01329 virtual int Compare(const void* p1,
01330 const void* p2,
01331 bool byte_swapped) const
01332 {
01333 if (!byte_swapped)
01334 return CBDB_FieldSimpleInt<Uint4>::Compare(p1, p2, byte_swapped);
01335
01336 Uint4 v1, v2;
01337 v1 = (Uint4)CByteSwap::GetInt4((unsigned char*)p1);
01338 v2 = (Uint4)CByteSwap::GetInt4((unsigned char*)p2);
01339 if (v1 < v2) return -1;
01340 if (v2 < v1) return 1;
01341 return 0;
01342 }
01343
01344 };
01345
01346
01347
01348
01349
01350
01351 class CBDB_FieldFloat : public CBDB_FieldSimpleFloat<float>
01352 {
01353 public:
01354 CBDB_FieldFloat& operator= (float val)
01355 {
01356 Set(val);
01357 return *this;
01358 }
01359
01360 CBDB_FieldFloat& operator= (const CBDB_FieldFloat& val)
01361 {
01362 Set(val);
01363 return *this;
01364 }
01365
01366 virtual CBDB_Field* Construct(size_t ) const
01367 {
01368 return new CBDB_FieldFloat();
01369 }
01370
01371 float Get() const
01372 {
01373 float v;
01374
01375 _ASSERT(!IsNull());
01376
01377 if (IsByteSwapped()) {
01378 v = CByteSwap::GetFloat((unsigned char*)GetBuffer());
01379 } else {
01380 #ifdef HAVE_UNALIGNED_READS
01381 TFieldType* b = (TFieldType*) this->GetBuffer();
01382 v = *b;
01383 #else
01384 ::memcpy(&v, GetBuffer(), sizeof(float));
01385 #endif
01386 }
01387 return v;
01388 }
01389
01390 virtual string GetString() const
01391 {
01392 double v = Get();
01393 return NStr::DoubleToString(v);
01394 }
01395
01396 virtual void ToString(string& str) const
01397 {
01398 double v = Get();
01399 NStr::DoubleToString(str, v);
01400 }
01401
01402 operator float() const
01403 {
01404 return Get();
01405 }
01406
01407 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
01408 {
01409 if (byte_swapped)
01410 return BDB_ByteSwap_FloatCompare;
01411
01412 return BDB_FloatCompare;
01413 }
01414
01415 virtual int Compare(const void* p1,
01416 const void* p2,
01417 bool byte_swapped) const
01418 {
01419 if (!byte_swapped)
01420 return CBDB_FieldSimpleFloat<float>::Compare(p1, p2, byte_swapped);
01421
01422 float v1, v2;
01423 v1 = CByteSwap::GetFloat((unsigned char*)p1);
01424 v2 = CByteSwap::GetFloat((unsigned char*)p2);
01425 if (v1 < v2) return -1;
01426 if (v2 < v1) return 1;
01427 return 0;
01428 }
01429 };
01430
01431
01432
01433
01434
01435 class CBDB_FieldDouble : public CBDB_FieldSimpleFloat<double>
01436 {
01437 public:
01438 CBDB_FieldDouble& operator= (double val)
01439 {
01440 Set(val);
01441 return *this;
01442 }
01443
01444 CBDB_FieldDouble& operator= (const CBDB_FieldDouble& val)
01445 {
01446 Set(val);
01447 return *this;
01448 }
01449
01450 virtual CBDB_Field* Construct(size_t ) const
01451 {
01452 return new CBDB_FieldDouble();
01453 }
01454
01455 double Get() const
01456 {
01457 double v;
01458
01459 _ASSERT(!IsNull());
01460
01461 if (IsByteSwapped()) {
01462 v = CByteSwap::GetDouble((unsigned char*)GetBuffer());
01463 } else {
01464 #ifdef HAVE_UNALIGNED_READS
01465 TFieldType* b = (TFieldType*) GetBuffer();
01466 v = *b;
01467 #else
01468 ::memcpy(&v, GetBuffer(), sizeof(double));
01469 #endif
01470 }
01471 return v;
01472 }
01473
01474 virtual string GetString() const
01475 {
01476 double v = Get();
01477 return NStr::DoubleToString(v);
01478 }
01479
01480 virtual void ToString(string& str) const
01481 {
01482 double v = Get();
01483 NStr::DoubleToString(str, v);
01484 }
01485
01486 operator double() const
01487 {
01488 return Get();
01489 }
01490
01491 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
01492 {
01493 if (byte_swapped)
01494 return BDB_ByteSwap_DoubleCompare;
01495
01496 return BDB_DoubleCompare;
01497 }
01498
01499 virtual int Compare(const void* p1,
01500 const void* p2,
01501 bool byte_swapped) const
01502 {
01503 if (!byte_swapped)
01504 return CBDB_FieldSimpleFloat<double>::Compare(p1, p2, byte_swapped);
01505
01506 double v1, v2;
01507 v1 = CByteSwap::GetDouble((unsigned char*)p1);
01508 v2 = CByteSwap::GetDouble((unsigned char*)p2);
01509 if (v1 < v2) return -1;
01510 if (v2 < v1) return 1;
01511 return 0;
01512 }
01513
01514 };
01515
01516
01517
01518 class CBDB_FieldFixedByteString : public CBDB_Field
01519 {
01520 public:
01521 CBDB_FieldFixedByteString();
01522
01523 virtual CBDB_Field* Construct(size_t buf_size) const
01524 {
01525 CBDB_FieldFixedByteString* fld = new CBDB_FieldFixedByteString();
01526 fld->SetBufferSize(buf_size ? buf_size : GetBufferSize());
01527 return fld;
01528 }
01529 operator const char* () const;
01530 CBDB_FieldFixedByteString& operator=
01531 (const CBDB_FieldFixedByteString& str);
01532
01533 void Set(const char* str);
01534 virtual void SetString (const char* val) { Set(val); }
01535 string Get() const;
01536 virtual string GetString() const { return Get(); }
01537
01538 bool IsEmpty() const { return false; }
01539 bool IsBlank() const { return false; }
01540
01541
01542
01543 virtual int Compare(const void* p1,
01544 const void* p2,
01545 bool ) const;
01546 virtual size_t GetDataLength(const void* buf) const;
01547 virtual void SetMinVal();
01548 virtual void SetMaxVal();
01549
01550 virtual void SetStdString(const string& str)
01551 {
01552 _ASSERT(str.length() == GetBufferSize());
01553 SetString(str.c_str());
01554 }
01555 virtual void ToString(string& str) const
01556 {
01557 str.assign((const char*) GetBuffer(), GetBufferSize());
01558 }
01559
01560 virtual BDB_CompareFunction GetCompareFunction(bool) const
01561 {
01562 return BDB_FixedByteStringCompare;
01563 }
01564
01565 };
01566
01567
01568
01569
01570
01571 class CBDB_FieldStringBase : public CBDB_Field
01572 {
01573 public:
01574 enum EOverflowAction {
01575 eThrowOnOverflow,
01576 eTruncateOnOverflow,
01577 eTruncateOnOverflowLogError
01578 };
01579
01580 protected:
01581 CBDB_FieldStringBase() : CBDB_Field(eVariableLength) {}
01582 };
01583
01584
01585
01586
01587
01588
01589 class CBDB_FieldString : public CBDB_FieldStringBase
01590 {
01591 public:
01592 CBDB_FieldString();
01593
01594
01595
01596 virtual CBDB_Field* Construct(size_t buf_size) const
01597 {
01598 CBDB_FieldString* fld = new CBDB_FieldString();
01599 fld->SetBufferSize(buf_size ? buf_size : GetBufferSize());
01600 return fld;
01601 }
01602
01603 operator const char* () const;
01604 CBDB_FieldString& operator= (const CBDB_FieldString& str);
01605 CBDB_FieldString& operator= (const char* str);
01606 CBDB_FieldString& operator= (const string& str);
01607
01608 void Set(const char* str, EOverflowAction if_overflow = eThrowOnOverflow);
01609 string Get() const { return string((const char*)GetBuffer()); }
01610
01611 virtual string GetString() const
01612 {
01613 return Get();
01614 }
01615
01616 bool IsEmpty() const;
01617 bool IsBlank() const;
01618
01619
01620
01621 virtual int Compare(const void* p1,
01622 const void* p2,
01623 bool ) const;
01624 virtual size_t GetDataLength(const void* buf) const;
01625 virtual void SetMinVal();
01626 virtual void SetMaxVal();
01627
01628 virtual void SetString(const char*);
01629 virtual void SetStdString(const string& str)
01630 {
01631 SetString(str.c_str());
01632 }
01633 virtual void ToString(string& str) const
01634 {
01635 str = (const char*) GetBuffer();
01636 }
01637
01638 virtual BDB_CompareFunction GetCompareFunction(bool) const
01639 {
01640 return BDB_StringCompare;
01641 }
01642 };
01643
01644
01645
01646
01647
01648
01649 class CBDB_FieldStringCase : public CBDB_FieldString
01650 {
01651 public:
01652 typedef CBDB_FieldString CParent;
01653
01654 explicit CBDB_FieldStringCase() : CBDB_FieldString() {}
01655
01656 virtual CBDB_Field* Construct(size_t buf_size) const
01657 {
01658 CBDB_FieldStringCase* fld = new CBDB_FieldStringCase();
01659 fld->SetBufferSize(buf_size ? buf_size : GetBufferSize());
01660 return fld;
01661 }
01662
01663
01664 operator const char* () const { return (const char*) GetBuffer(); }
01665
01666 CBDB_FieldStringCase& operator= (const CBDB_FieldString& str)
01667 {
01668 Set(str);
01669 return *this;
01670 }
01671 CBDB_FieldStringCase& operator= (const CBDB_FieldStringCase& str)
01672 {
01673 Set(str);
01674 return *this;
01675 }
01676 CBDB_FieldStringCase& operator= (const char* str)
01677 {
01678 Set(str);
01679 return *this;
01680 }
01681 CBDB_FieldStringCase& operator= (const string& str)
01682 {
01683 Set(str.c_str());
01684 return *this;
01685 }
01686
01687 virtual int Compare(const void* p1,
01688 const void* p2,
01689 bool) const
01690 {
01691 _ASSERT(p1 && p2);
01692 return NStr::CompareNocase((const char*) p1, (const char*) p2);
01693 }
01694
01695 virtual
01696 BDB_CompareFunction GetCompareFunction(bool ) const
01697 {
01698 return BDB_StringCaseCompare;
01699 }
01700
01701 };
01702
01703
01704
01705
01706
01707
01708 class CBDB_FieldLString : public CBDB_FieldStringBase
01709 {
01710 public:
01711 CBDB_FieldLString();
01712
01713
01714
01715 virtual CBDB_Field* Construct(size_t buf_size) const;
01716
01717 operator string() const { return GetString(); }
01718 CBDB_FieldLString& operator= (const CBDB_FieldLString& str);
01719 CBDB_FieldLString& operator= (const char* str);
01720 CBDB_FieldLString& operator= (const string& str);
01721
01722 void Set(const char* str, EOverflowAction if_overflow = eThrowOnOverflow);
01723 void Set(const char* str, size_t size,
01724 EOverflowAction if_overflow = eThrowOnOverflow);
01725 string Get() const;
01726
01727 virtual string GetString() const
01728 {
01729 return Get();
01730 }
01731
01732 bool IsEmpty() const;
01733 bool IsBlank() const;
01734
01735
01736
01737 virtual int Compare(const void* p1,
01738 const void* p2,
01739 bool ) const;
01740 virtual size_t GetDataLength(const void* buf) const;
01741 virtual void SetMinVal();
01742 virtual void SetMaxVal();
01743
01744 virtual void SetString(const char*);
01745 virtual void SetStdString(const string& str);
01746
01747 virtual BDB_CompareFunction GetCompareFunction(bool) const
01748 {
01749 return BDB_LStringCompare;
01750 }
01751 virtual void ToString(string& str) const;
01752 protected:
01753 const unsigned char* GetLString(const unsigned char* str,
01754 bool check_legacy,
01755 int* str_len) const;
01756 virtual size_t GetExtraDataLength();
01757 };
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767 class CBDB_BufferManager
01768 {
01769 public:
01770
01771 unsigned int FieldCount() const;
01772
01773 const CBDB_Field& GetField(unsigned int idx) const;
01774 CBDB_Field& GetField(unsigned int idx);
01775
01776
01777
01778 int GetFieldIndex(const string& name) const;
01779
01780
01781 bool IsByteSwapped() const { return m_ByteSwapped; }
01782
01783
01784
01785 void SetFieldCompareLimit(unsigned int n_fields);
01786
01787
01788
01789 unsigned int GetFieldCompareLimit() const;
01790
01791
01792
01793 bool IsLegacyStrings() const { return m_LegacyString; }
01794
01795
01796
01797 size_t GetDBT_Size() const { return m_DBT_Size; }
01798
01799 ~CBDB_BufferManager();
01800
01801
01802 bool HasNull() const;
01803
01804
01805 void CopyFrom(const CBDB_BufferManager& bman);
01806
01807
01808 void CopyPackedFrom(void* data, size_t data_size);
01809
01810 protected:
01811 CBDB_BufferManager();
01812
01813
01814 void Construct();
01815
01816
01817 void SetMinVal(unsigned int idx_from, unsigned int idx_to);
01818
01819
01820 void SetMaxVal(unsigned int idx_from, unsigned int idx_to);
01821
01822
01823
01824
01825
01826 void Bind(CBDB_Field* field, ENullable is_nullable = eNotNullable);
01827
01828
01829 void CopyFieldsFrom(const CBDB_BufferManager& buf_mgr);
01830
01831
01832
01833
01834
01835
01836 void DuplicateStructureFrom(const CBDB_BufferManager& buf_mgr);
01837
01838
01839
01840
01841
01842 int Compare(const CBDB_BufferManager& buf_mgr,
01843 unsigned int n_fields = 0) const;
01844
01845
01846
01847 bool IsPackable() const;
01848
01849
01850
01851 void CheckNullConstraint() const;
01852
01853 void ArrangePtrsUnpacked();
01854 void ArrangePtrsPacked();
01855 void Clear();
01856 unsigned Pack();
01857 unsigned Unpack();
01858
01859
01860 void PrepareDBT_ForWrite(DBT* dbt);
01861
01862
01863 void PrepareDBT_ForRead(DBT* dbt);
01864
01865
01866 size_t ComputeBufferSize() const;
01867
01868
01869 bool IsNullable() const;
01870
01871
01872 void SetByteSwapped(bool byte_swapped) { m_ByteSwapped = byte_swapped; }
01873
01874
01875
01876 void SetNullable();
01877
01878 void SetNull(unsigned int field_idx, bool value);
01879 bool IsNull (unsigned int field_idx) const;
01880
01881 size_t ComputeNullSetSize() const;
01882 bool TestNullBit(unsigned int idx) const;
01883 void SetNullBit (unsigned int idx, bool value);
01884 void SetAllNull();
01885
01886
01887 BDB_CompareFunction GetCompareFunction() const;
01888
01889
01890 BDB_HashFunction GetHashFunction() const;
01891
01892
01893 void SetLegacyStringsCheck(bool value) { m_LegacyString = value; }
01894
01895 void SetDBT_Size(size_t size) { m_DBT_Size = size; }
01896
01897
01898 void SetFieldOwnership(bool own_fields) { m_OwnFields = own_fields; }
01899
01900
01901 bool IsOwnFields() const { return m_OwnFields; }
01902
01903
01904 void SetPackable(bool packable) { m_Packable = packable; }
01905
01906 private:
01907 void x_ComputePackOpt();
01908 private:
01909 CBDB_BufferManager(const CBDB_BufferManager&);
01910 CBDB_BufferManager& operator= (const CBDB_BufferManager&);
01911
01912 private:
01913 typedef vector<CBDB_Field*> TFieldVector;
01914
01915 private:
01916 TFieldVector m_Fields;
01917
01918 vector<void*> m_Ptrs;
01919 char* m_Buffer;
01920 size_t m_BufferSize;
01921 size_t m_PackedSize;
01922 size_t m_DBT_Size;
01923 bool m_Packable;
01924
01925 bool m_ByteSwapped;
01926
01927
01928 bool m_Nullable;
01929
01930 size_t m_NullSetSize;
01931
01932
01933 unsigned int m_CompareLimit;
01934
01935
01936 bool m_LegacyString;
01937
01938
01939 bool m_OwnFields;
01940
01941
01942
01943
01944
01945 bool m_PackOptComputed;
01946
01947 unsigned int m_FirstVarFieldIdx;
01948
01949 unsigned int m_FirstVarFieldIdxOffs;
01950
01951 private:
01952 friend class CBDB_Field;
01953 friend class CBDB_BLobFile;
01954 friend class CBDB_File;
01955 friend class CBDB_FileCursor;
01956 friend class CBDB_FC_Condition;
01957 };
01958
01959
01960 class CBDB_FieldFactory
01961 {
01962 public:
01963 enum EType
01964 {
01965 eUnknown,
01966
01967 eString,
01968 eLString,
01969 eInt8,
01970 eInt4,
01971 eUint4,
01972 eInt2,
01973 eUint1,
01974 eFloat,
01975 eDouble,
01976 eUChar,
01977 eBlob
01978 };
01979
01980 public:
01981 CBDB_FieldFactory();
01982
01983
01984 EType GetType(const string& type) const;
01985
01986
01987 CBDB_Field* Create(EType type) const;
01988
01989
01990
01991
01992
01993
01994 CBDB_Field* Create(const string& type) const;
01995 };
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007 template <class Type>
02008 struct SBDB_TypeTraits
02009 {
02010 typedef Type TType;
02011 typedef void* TFieldType;
02012 };
02013
02014
02015
02016
02017
02018 template<>
02019 struct SBDB_TypeTraits<Int1>
02020 {
02021 typedef Int4 TType;
02022 typedef CBDB_FieldInt1 TFieldType;
02023 };
02024
02025 template<>
02026 struct SBDB_TypeTraits<Uint1>
02027 {
02028 typedef Uint4 TType;
02029 typedef CBDB_FieldUint1 TFieldType;
02030 };
02031
02032
02033
02034
02035
02036 template<>
02037 struct SBDB_TypeTraits<Int2>
02038 {
02039 typedef Int4 TType;
02040 typedef CBDB_FieldInt2 TFieldType;
02041 };
02042
02043 template<>
02044 struct SBDB_TypeTraits<Uint2>
02045 {
02046 typedef Uint4 TType;
02047 typedef CBDB_FieldUint2 TFieldType;
02048 };
02049
02050
02051
02052
02053
02054 template<>
02055 struct SBDB_TypeTraits<Int4>
02056 {
02057 typedef Int4 TType;
02058 typedef CBDB_FieldInt4 TFieldType;
02059 };
02060
02061 template<>
02062 struct SBDB_TypeTraits<Uint4>
02063 {
02064 typedef Uint4 TType;
02065 typedef CBDB_FieldUint4 TFieldType;
02066 };
02067
02068
02069
02070
02071
02072 template<>
02073 struct SBDB_TypeTraits<Int8>
02074 {
02075 typedef Int8 TType;
02076 typedef CBDB_FieldInt8 TFieldType;
02077 };
02078
02079 template<>
02080 struct SBDB_TypeTraits<Uint8>
02081 {
02082 typedef Uint8 TType;
02083 typedef CBDB_FieldUint8 TFieldType;
02084 };
02085
02086
02087
02088
02089
02090 template<>
02091 struct SBDB_TypeTraits<string>
02092 {
02093 typedef string TType;
02094 typedef CBDB_FieldString TFieldType;
02095 };
02096
02097
02098
02099
02100
02101 template<>
02102 struct SBDB_TypeTraits<float>
02103 {
02104 typedef float TType;
02105 typedef CBDB_FieldFloat TFieldType;
02106 };
02107
02108 template<>
02109 struct SBDB_TypeTraits<double>
02110 {
02111 typedef double TType;
02112 typedef CBDB_FieldDouble TFieldType;
02113 };
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128 inline bool CBDB_Field::IsVariableLength() const
02129 {
02130 return m_Flags.VariableLength == 1;
02131 }
02132
02133
02134 inline size_t CBDB_Field::GetBufferSize() const
02135 {
02136 return m_BufferSize;
02137 }
02138
02139
02140 inline bool CBDB_Field::IsBufferAttached() const
02141 {
02142 return m_Flags.Attached == 1;
02143 }
02144
02145
02146 inline bool CBDB_Field::IsNullable() const
02147 {
02148 return m_Flags.Nullable == 1;
02149 }
02150
02151
02152 inline void CBDB_Field::SetNullable()
02153 {
02154 m_Flags.Nullable = 1;
02155 }
02156
02157
02158 inline void CBDB_Field::SetNotNull()
02159 {
02160 m_BufferManager->SetNull(m_BufferIdx, false);
02161 }
02162
02163
02164 inline void CBDB_Field::SetNull()
02165 {
02166 _ASSERT(m_BufferManager->IsNullable());
02167 m_BufferManager->SetNull(m_BufferIdx, true);
02168 }
02169
02170
02171 inline bool CBDB_Field::IsNull() const
02172 {
02173 return m_BufferManager->IsNull(m_BufferIdx);
02174 }
02175
02176
02177 inline void* CBDB_Field::Unpack()
02178 {
02179 _ASSERT(m_BufferManager);
02180 m_BufferManager->Unpack();
02181 return GetBuffer();
02182 }
02183
02184
02185 inline void CBDB_Field::SetBuffer(void* buf, size_t buf_size)
02186 {
02187 m_Buffer = buf;
02188 if ( buf_size )
02189 m_BufferSize = buf_size;
02190 m_Flags.Attached = 1;
02191 }
02192
02193
02194 inline void CBDB_Field::SetBufferSize(size_t buf_size)
02195 {
02196 _ASSERT(buf_size != 0);
02197 m_BufferSize = buf_size;
02198 }
02199
02200
02201 inline void CBDB_Field::SetDataSize(size_t size)
02202 {
02203 m_BufferSize = size + GetExtraDataLength();
02204 }
02205
02206
02207 inline void CBDB_Field::SetBufferIdx(unsigned int idx)
02208 {
02209 m_BufferIdx = idx;
02210 }
02211
02212
02213 inline const void* CBDB_Field::GetBuffer() const
02214 {
02215 return m_Buffer;
02216 }
02217
02218
02219 inline void* CBDB_Field::GetBuffer()
02220 {
02221 return m_Buffer;
02222 }
02223
02224
02225 inline void CBDB_Field::SetBufferManager(CBDB_BufferManager* owner)
02226 {
02227 _ASSERT(owner);
02228 m_BufferManager = owner;
02229 }
02230
02231
02232 inline size_t CBDB_Field::GetLength() const
02233 {
02234 return GetDataLength(m_Buffer);
02235 }
02236
02237
02238 inline int CBDB_Field::CompareWith(const CBDB_Field& field) const
02239 {
02240 bool byte_swapped = m_BufferManager->IsByteSwapped();
02241 return Compare(GetBuffer(), field.GetBuffer(), byte_swapped);
02242 }
02243
02244
02245 inline bool CBDB_Field::IsSameType(const CBDB_Field& field) const
02246 {
02247 try {
02248 const type_info& t1 = typeid(*this);
02249 const type_info& t2 = typeid(field);
02250 return (t1 == t2) != 0;
02251 } catch (...) {
02252 }
02253 return false;
02254 }
02255
02256
02257
02258 inline void CBDB_Field::CopyFrom(const CBDB_Field& src)
02259 {
02260 if (this == &src)
02261 return;
02262
02263 if ( !IsSameType(src) ) {
02264 BDB_THROW(eType, "Wrong field type");
02265 }
02266
02267 CopyFrom(src.GetBuffer());
02268 }
02269
02270
02271 inline void CBDB_Field::CopyFrom(const void* src_buf)
02272 {
02273 _ASSERT(src_buf);
02274
02275 void* dst_ptr = Unpack();
02276 _ASSERT(dst_ptr);
02277
02278 size_t max_len = GetBufferSize();
02279 size_t copy_len = GetDataLength(src_buf);
02280
02281 if (copy_len > max_len) {
02282 BDB_THROW(eOverflow, "Cannot copy. Data length exceeds max value");
02283 }
02284 ::memcpy(dst_ptr, src_buf, copy_len);
02285 SetNotNull();
02286 }
02287
02288
02289 inline const string& CBDB_Field::GetName() const
02290 {
02291 return m_Name;
02292 }
02293
02294
02295 inline void CBDB_Field::SetName(const char* name)
02296 {
02297 _ASSERT(name);
02298 m_Name = name;
02299 }
02300
02301 inline bool CBDB_Field::IsByteSwapped() const
02302 {
02303 return m_BufferManager->IsByteSwapped();
02304 }
02305
02306
02307
02308
02309
02310 inline CBDB_FieldFixedByteString::operator const char* () const
02311 {
02312 const char* str = (const char*) GetBuffer();
02313 _ASSERT(str);
02314 return str;
02315 }
02316
02317
02318 inline
02319 void CBDB_FieldFixedByteString::Set(const char* str)
02320 {
02321 ::memcpy((char*)GetBuffer(), str, GetBufferSize());
02322 }
02323
02324 inline
02325 string CBDB_FieldFixedByteString::Get() const
02326 {
02327 _ASSERT(!IsNull());
02328
02329 const char* buf = (const char*) GetBuffer();
02330 return string(buf, GetBufferSize());
02331 }
02332
02333 inline
02334 int CBDB_FieldFixedByteString::Compare(const void* p1,
02335 const void* p2,
02336 bool ) const
02337 {
02338 return ::memcmp(p1, p2, GetBufferSize());
02339 }
02340
02341 inline
02342 size_t CBDB_FieldFixedByteString::GetDataLength(const void* buf) const
02343 {
02344 return GetBufferSize();
02345 }
02346
02347 inline
02348 void CBDB_FieldFixedByteString::SetMinVal()
02349 {
02350 void* buf = Unpack();
02351 ::memset(buf, 0, GetBufferSize());
02352 }
02353
02354 inline
02355 void CBDB_FieldFixedByteString::SetMaxVal()
02356 {
02357 void* buf = Unpack();
02358 ::memset(buf, 0xFF, GetBufferSize());
02359 }
02360
02361
02362
02363
02364
02365 inline CBDB_FieldString::CBDB_FieldString()
02366 : CBDB_FieldStringBase()
02367 {
02368 SetBufferSize(256);
02369 }
02370
02371
02372 inline CBDB_FieldString::operator const char* () const
02373 {
02374 const char* str = (const char*) GetBuffer();
02375 _ASSERT(str);
02376 return str;
02377 }
02378
02379
02380 inline
02381 CBDB_FieldString&
02382 CBDB_FieldString::operator= (const CBDB_FieldString& str)
02383 {
02384 if (this == &str)
02385 return *this;
02386
02387 size_t len = str.GetLength();
02388 if (len > GetBufferSize()) {
02389
02390 BDB_THROW(eOverflow, "String field overflow.");
02391 }
02392 Unpack();
02393 ::strcpy((char*)GetBuffer(), (const char*) str);
02394
02395 if ( str.IsNull() ) {
02396 SetNull();
02397 } else {
02398 SetNotNull();
02399 }
02400
02401 return *this;
02402 }
02403
02404
02405 inline
02406 void CBDB_FieldString::Set(const char* str, EOverflowAction if_overflow)
02407 {
02408 if ( !str )
02409 str = kEmptyCStr;
02410
02411 size_t new_len = ::strlen(str) + 1;
02412
02413
02414 if (new_len > GetBufferSize()) {
02415 switch (if_overflow) {
02416 case eTruncateOnOverflowLogError:
02417 LOG_POST(Warning << "Value truncated for field '"
02418 << GetName() << "'");
02419
02420 case eTruncateOnOverflow:
02421 new_len = GetBufferSize();
02422 break;
02423 case eThrowOnOverflow:
02424 string msg("String field '");
02425 msg += GetName();
02426 msg += "' overflow: max size = ";
02427 msg += NStr::IntToString(GetBufferSize());
02428 msg += ", assignee size = ";
02429 msg += NStr::IntToString(new_len);
02430 BDB_THROW(eOverflow, msg);
02431 break;
02432 }
02433 }
02434 Unpack();
02435 ::memcpy(GetBuffer(), str, new_len);
02436 SetNotNull();
02437 }
02438
02439 inline
02440 void CBDB_FieldString::SetString(const char* str)
02441 {
02442 operator=(str);
02443 }
02444
02445 inline int CBDB_FieldString::Compare(const void* p1,
02446 const void* p2,
02447 bool ) const
02448 {
02449 _ASSERT(p1 && p2);
02450 return ::strcmp((const char*) p1, (const char*) p2);
02451 }
02452
02453
02454 inline void CBDB_FieldString::SetMinVal()
02455 {
02456 ((char*) Unpack())[0] = '\0';
02457 }
02458
02459
02460 inline void CBDB_FieldString::SetMaxVal()
02461 {
02462 void* buf = Unpack();
02463
02464
02465 ::memset(buf, 0x7F, GetBufferSize());
02466 ((char*) buf)[GetBufferSize() - 1] = '\0';
02467
02468 SetNotNull();
02469 }
02470
02471
02472 inline bool CBDB_FieldString::IsEmpty() const
02473 {
02474 const char* str = (const char*) GetBuffer();
02475 _ASSERT(str);
02476 return !*str;
02477 }
02478
02479
02480 inline bool CBDB_FieldString::IsBlank() const
02481 {
02482 const char* str = (const char*) GetBuffer();
02483 _ASSERT(str);
02484 for (; *str; ++str) {
02485 if ( !isspace((unsigned char)(*str)) )
02486 return false;
02487 }
02488 return true;
02489 }
02490
02491
02492 inline size_t CBDB_FieldString::GetDataLength(const void* buf) const
02493 {
02494 _ASSERT(buf);
02495 return ::strlen((const char*) buf) + 1;
02496 }
02497
02498
02499 inline CBDB_FieldString& CBDB_FieldString::operator= (const char* str)
02500 {
02501 Set(str, eThrowOnOverflow);
02502 return *this;
02503 }
02504
02505 inline CBDB_FieldString& CBDB_FieldString::operator= (const string& str)
02506 {
02507 return this->operator=(str.c_str());
02508 }
02509
02510
02511
02512
02513
02514
02515
02516
02517 inline const CBDB_Field& CBDB_BufferManager::GetField(unsigned int n) const
02518 {
02519 return *m_Fields[n];
02520 }
02521
02522
02523 inline CBDB_Field& CBDB_BufferManager::GetField(unsigned int n)
02524 {
02525 return *m_Fields[n];
02526 }
02527
02528
02529 inline unsigned int CBDB_BufferManager::FieldCount() const
02530 {
02531 return (unsigned int)m_Fields.size();
02532 }
02533
02534
02535 inline bool CBDB_BufferManager::IsPackable() const
02536 {
02537 return m_Packable;
02538 }
02539
02540
02541 inline bool CBDB_BufferManager::IsNullable() const
02542 {
02543 return m_Nullable;
02544 }
02545
02546
02547 inline void CBDB_BufferManager::SetNullable()
02548 {
02549 _ASSERT(m_Buffer == 0);
02550 m_Nullable = true;
02551 }
02552
02553
02554 inline size_t CBDB_BufferManager::ComputeNullSetSize() const
02555 {
02556 if ( !IsNullable() )
02557 return 0;
02558
02559 return (FieldCount() + 7) / 8;
02560 }
02561
02562
02563 inline bool CBDB_BufferManager::TestNullBit(unsigned int n) const
02564 {
02565 _ASSERT(IsNullable());
02566
02567 const unsigned char* buf = (unsigned char*) m_Buffer;
02568 unsigned char mask = (unsigned char) (1 << (n & 7));
02569 const unsigned char* offs = buf + (n >> 3);
02570
02571 return ((*offs) & mask) != 0;
02572 }
02573
02574
02575 inline void CBDB_BufferManager::SetNullBit(unsigned int n, bool value)
02576 {
02577 _ASSERT(IsNullable());
02578
02579 unsigned char* buf = (unsigned char*) m_Buffer;
02580 unsigned char mask = (unsigned char) (1 << (n & 7));
02581 unsigned char* offs = buf + (n >> 3);
02582
02583 (void) (value ? (*offs |= mask) : (*offs &= ~mask));
02584 }
02585
02586
02587 inline void CBDB_BufferManager::SetNull(unsigned int field_idx, bool value)
02588 {
02589 if ( !IsNullable() )
02590 return;
02591 _ASSERT(field_idx < m_Fields.size());
02592 SetNullBit(field_idx, value);
02593 }
02594
02595
02596 inline void CBDB_BufferManager::SetAllNull()
02597 {
02598 if ( !IsNullable() )
02599 return;
02600 unsigned char* buf = (unsigned char*) m_Buffer;
02601 for (size_t i = 0; i < m_NullSetSize; ++i) {
02602 *buf++ = (unsigned char) 0xFF;
02603 }
02604 }
02605
02606
02607 inline bool CBDB_BufferManager::HasNull() const
02608 {
02609 if (IsNullable()) {
02610 for (size_t i = 0; i < m_NullSetSize; ++i) {
02611 if (m_Buffer[i])
02612 return true;
02613 }
02614 }
02615 return false;
02616 }
02617
02618
02619 inline bool CBDB_BufferManager::IsNull(unsigned field_idx) const
02620 {
02621 if ( !IsNullable() )
02622 return false;
02623
02624 _ASSERT(field_idx < m_Fields.size());
02625
02626 return TestNullBit(field_idx);
02627 }
02628
02629
02630 inline void CBDB_BufferManager::ArrangePtrsUnpacked()
02631 {
02632 if ( !m_PackedSize )
02633 return;
02634
02635 if ( !IsPackable() ) {
02636 m_PackedSize = 0;
02637 return;
02638 }
02639
02640 for (size_t i = 0; i < m_Fields.size(); ++i) {
02641 CBDB_Field& df = GetField((unsigned)i);
02642 df.SetBuffer(m_Ptrs[i]);
02643 }
02644
02645 m_PackedSize = 0;
02646 }
02647
02648
02649 inline void CBDB_BufferManager::Clear()
02650 {
02651 ::memset(m_Buffer, 0, m_BufferSize);
02652 ArrangePtrsUnpacked();
02653 }
02654
02655
02656 inline
02657 void CBDB_BufferManager::CopyFieldsFrom(const CBDB_BufferManager& buf_mgr)
02658 {
02659 unsigned int field_count = min(FieldCount(), buf_mgr.FieldCount());
02660
02661 for (unsigned int i = 0; i < field_count; ++i) {
02662 CBDB_Field* fld = m_Fields[i];
02663 fld->CopyFrom(buf_mgr.GetField(i));
02664 }
02665 }
02666
02667
02668 inline
02669 void CBDB_BufferManager::SetMinVal(unsigned int idx_from, unsigned int idx_to)
02670 {
02671 _ASSERT(idx_to <= FieldCount());
02672
02673 for ( ; idx_from < idx_to; ++idx_from) {
02674 CBDB_Field& fld = GetField(idx_from);
02675 fld.SetMinVal();
02676 }
02677 }
02678
02679
02680 inline
02681 void CBDB_BufferManager::SetMaxVal(unsigned int idx_from, unsigned int idx_to)
02682 {
02683 _ASSERT(idx_to <= FieldCount());
02684
02685 for ( ; idx_from < idx_to; ++idx_from) {
02686 CBDB_Field& fld = GetField(idx_from);
02687 fld.SetMaxVal();
02688 }
02689 }
02690
02691 inline
02692 void CBDB_BufferManager::SetFieldCompareLimit(unsigned int n_fields)
02693 {
02694 m_CompareLimit = n_fields;
02695 }
02696
02697 inline
02698 unsigned int CBDB_BufferManager::GetFieldCompareLimit() const
02699 {
02700 return m_CompareLimit;
02701 }
02702
02703
02704
02705
02706
02707 inline
02708 void DeleteFields(CBDB_BufferManager& buf)
02709 {
02710 for (unsigned int i = 0; i < buf.FieldCount(); ++i) {
02711 CBDB_Field* fld = &buf.GetField(i);
02712 delete fld;
02713 }
02714 }
02715
02716
02717 END_NCBI_SCOPE
02718
02719
02720
02721 #endif
02722
02723