00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __CLASS_H__
00012 #define __CLASS_H__
00013
00014 #include "stdtp.h"
00015 #include "sync.h"
00016 #include "rectangle.h"
00017
00018 BEGIN_GIGABASE_NAMESPACE
00019
00020 #ifndef dbDatabaseOffsetBits
00021 #ifdef LARGE_DATABASE_SUPPORT
00022 #define dbDatabaseOffsetBits 40 // up to 1 terabyte
00023 #else
00024 #define dbDatabaseOffsetBits 32 // 37 - 128Gb, 40 - up to 1 terabyte
00025 #endif
00026 #endif
00027
00028 #ifndef dbDatabaseOidBits
00029 #define dbDatabaseOidBits 32
00030 #endif
00031
00035 #if dbDatabaseOidBits > 32
00036 typedef nat8 oid_t;
00037 #else
00038 typedef nat4 oid_t;
00039 #endif
00040
00044 #if dbDatabaseOffsetBits > 32
00045 typedef nat8 offs_t;
00046 typedef db_int8 soffs_t;
00047 #else
00048 typedef nat4 offs_t;
00049 typedef int4 soffs_t;
00050 #endif
00051
00052 #include "selection.h"
00053
00057 enum dbIndexType {
00058 HASHED = 1,
00059 INDEXED = 2,
00060 CASE_INSENSITIVE = 4,
00061
00062 DB_FIELD_CASCADE_DELETE = 8,
00063 UNIQUE = 16,
00064
00065 AUTOINCREMENT = 32,
00066 OPTIMIZE_DUPLICATES = 64,
00067 DB_BLOB_CASCADE_DELETE = 128,
00068
00069 DB_TIMESTAMP = 256,
00070
00071 DB_FIELD_INHERITED_MASK = ~(HASHED|INDEXED)
00072 };
00073
00077 #define KEY(x, index) \
00078 *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00079 sizeof(x), index), x)
00080
00081 #define KEY_WITH_DEFAULT(x, index, defaultValue) \
00082 *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00083 sizeof(x), index), x, defaultValue)
00084
00088 #define FIELD(x) KEY(x, 0)
00089
00090 #define FIELD_WITH_DEFAULT(x, defaultValue) KEY_WITH_DEF(x, 0, defaultValue)
00091
00092
00096 typedef int (*dbUDTComparator)(void*, void*, size_t);
00097
00101 #define UDT(x, index, comparator) \
00102 *GB_NS::dbDescribeRawField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00103 sizeof(x), index), (GB_NS::dbUDTComparator)comparator)
00104
00108 #define RAWFIELD(x) UDT(x, 0, &memcmp)
00109
00113 #define RAWKEY(x, index) UDT(x, index, &memcmp)
00114
00115
00121 #define RELATION(x,inverse) \
00122 *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00123 sizeof(x), 0, STRLITERAL(#inverse)), x)
00124
00130 #define INDEXED_RELATION(x,inverse) \
00131 *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00132 sizeof(x), GB_NS::INDEXED, STRLITERAL(#inverse)), x)
00133
00139 #define OWNER(x,member) \
00140 *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00141 sizeof(x), GB_NS::DB_FIELD_CASCADE_DELETE, \
00142 STRLITERAL(#member)), x)
00143
00147 #define METHOD(x) \
00148 *GB_NS::dbDescribeMethod(new GB_NS::dbFieldDescriptor(STRLITERAL(#x)), &self::x)
00149
00156 #define BLOB(x) \
00157 *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00158 sizeof(x), GB_NS::DB_BLOB_CASCADE_DELETE), x)
00159
00162 #define SUPERCLASS(x) \
00163 x::dbDescribeComponents(NULL)->adjustOffsets((char*)((x*)this)-(char*)this)
00164
00169 #define TYPE_DESCRIPTOR(fields) \
00170 GB_NS::dbFieldDescriptor* dbDescribeComponents(GB_NS::dbFieldDescriptor*) { \
00171 return &fields; \
00172 } \
00173 static GB_NS::dbTableDescriptor dbDescriptor
00174
00180 #define CLASS_DESCRIPTOR(name, fields) \
00181 typedef name self; \
00182 GB_NS::dbFieldDescriptor* dbDescribeComponents(GB_NS::dbFieldDescriptor*) { \
00183 return &fields; \
00184 } \
00185 static GB_NS::dbTableDescriptor dbDescriptor
00186
00190 #if (defined(_MSC_VER) && _MSC_VER+0 < 1200) || defined(__MWERKS__)
00191 #if defined(_MSC_VER)
00192 #define GET_TABLE_DESC_PREFIX
00193 #else
00194 #define GET_TABLE_DESC_PREFIX template<>
00195 #endif
00196 #define GET_TABLE_DESC_PARAM(T) <T>(T*)
00197 #else
00198 #define GET_TABLE_DESC_PREFIX
00199 #define GET_TABLE_DESC_PARAM(T) (T*)
00200 #endif
00201
00202 #if defined(_MSC_VER) && _MSC_VER+0 <= 1300
00203 #define TABLE_DESC_PREFIX
00204 #else
00205 #define TABLE_DESC_PREFIX template<>
00206 #endif
00207
00208 #define REGISTER_IN(table, database) \
00209 GET_TABLE_DESC_PREFIX GB_NS::dbTableDescriptor* dbGetTableDescriptor GET_TABLE_DESC_PARAM(table) \
00210 { return &table::dbDescriptor; } \
00211 static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##table() \
00212 { return ((table*)0)->dbDescribeComponents(NULL); } \
00213 GB_NS::dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00214 &dbDescribeComponentsOf##table)
00215
00216 #define REGISTER_TEMPLATE_IN(table, database) \
00217 GET_TABLE_DESC_PREFIX GB_NS::dbTableDescriptor* dbGetTableDescriptor GET_TABLE_DESC_PARAM(table) \
00218 { return &table::dbDescriptor; } \
00219 static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##table() \
00220 { return ((table*)0)->dbDescribeComponents(NULL); } \
00221 TABLE_DESC_PREFIX GB_NS::dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00222 &dbDescribeComponentsOf##table)
00223
00224 #define REGISTER_IN_NS(ns, table, database) \
00225 GET_TABLE_DESC_PREFIX GB_NS::dbTableDescriptor* dbGetTableDescriptor GET_TABLE_DESC_PARAM(ns::table) \
00226 { return &ns::table::dbDescriptor; } \
00227 static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##ns##__##table() \
00228 { return ((ns::table*)0)->dbDescribeComponents(NULL); } \
00229 GB_NS::dbTableDescriptor ns::table::dbDescriptor(_T(ns##__##table), database, sizeof(ns::table), \
00230 &dbDescribeComponentsOf##ns##__##table)
00231
00232 #define REGISTER_TEMPLATE_IN_NS(ns, table, database) \
00233 GET_TABLE_DESC_PREFIX GB_NS::dbTableDescriptor* dbGetTableDescriptor GET_TABLE_DESC_PARAM(ns::table) \
00234 { return &ns::table::dbDescriptor; } \
00235 static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##ns##__##table() \
00236 { return ((ns::table*)0)->dbDescribeComponents(NULL); } \
00237 TABLE_DESC_PREFIX GB_NS::dbTableDescriptor ns::table::dbDescriptor(_T(ns##__##table), database, sizeof(ns::table), \
00238 &dbDescribeComponentsOf##ns##__##table)
00239
00240
00245 #define REGISTER(table) REGISTER_IN(table, NULL)
00246 #define REGISTER_TEMPLATE(table) REGISTER_TEMPLATE_IN(table, NULL)
00247 #define REGISTER_NS(ns, table) REGISTER_IN_NS(ns, table, NULL)
00248 #define REGISTER_TEMPLATE_NS(ns, table) REGISTER_TEMPLATE_IN_NS(ns, table, NULL)
00249
00254 #define DETACHED_TABLE ((GB_NS::dbDatabase*)-1)
00255 #define REGISTER_UNASSIGNED(table) REGISTER_IN(table, DETACHED_TABLE)
00256 #define REGISTER_TEMPLATE_UNASSIGNED(table) REGISTER_TEMPLATE_IN(table, DETACHED_TABLE)
00257 #define REGISTER_UNASSIGNED_NS(ns, table) REGISTER_IN_NS(ns, table, DETACHED_TABLE)
00258 #define REGISTER_TEMPLATE_UNASSIGNED_NS(ns, table) REGISTER_TEMPLATE_IN_NS(ns, table, DETACHED_TABLE)
00259
00260
00261 class dbDatabase;
00262 class dbSession;
00263 class dbAnyArray;
00264 class dbTableDescriptor;
00265 class dbAnyMethodTrampoline;
00266 class dbTable;
00267
00271 class GIGABASE_DLL_ENTRY dbFieldDescriptor {
00272 public:
00276 dbFieldDescriptor* next;
00277
00281 dbFieldDescriptor* prev;
00282
00286 dbFieldDescriptor* nextField;
00287
00291 dbFieldDescriptor* nextHashedField;
00292
00296 dbFieldDescriptor* nextIndexedField;
00297
00301 dbFieldDescriptor* nextInverseField;
00302
00306 int fieldNo;
00307
00311 char_t* name;
00312
00316 char_t* longName;
00317
00321 char_t* refTableName;
00322
00326 dbTableDescriptor* refTable;
00327
00331 dbTableDescriptor* defTable;
00332
00336 dbFieldDescriptor* inverseRef;
00337
00341 char_t* inverseRefName;
00342
00346 int type;
00347
00351 int appType;
00352
00356 int indexType;
00357
00361 union {
00362 bool Bool;
00363 int1 Int1; int2 Int2; int4 Int4; db_int8 Db_Int8;
00364 real4 Real4; real8 Real8;
00365 } defaultValue;
00366
00370 int dbsOffs;
00371
00375 int appOffs;
00376
00380 dbFieldDescriptor* components;
00381
00385 oid_t hashTable;
00386
00390 oid_t bTree;
00391
00395 size_t dbsSize;
00396
00400 size_t appSize;
00401
00406 size_t alignment;
00407
00411 dbUDTComparator comparator;
00412
00416 enum FieldAttributes {
00417 ComponentOfArray = 0x01,
00418 HasArrayComponents = 0x02,
00419 OneToOneMapping = 0x04,
00420 Updated = 0x08,
00421 HasArrayOfArrayComponents = 0x10
00422 };
00423 int attr;
00424
00428 int oldDbsType;
00432 int oldDbsOffs;
00436 int oldDbsSize;
00437
00438
00442 dbAnyMethodTrampoline* method;
00443
00447 void (*arrayAllocator)(dbAnyArray* array, void* data, size_t length);
00448
00459 size_t calculateRecordSize(byte* base, size_t offs);
00460
00470 size_t calculateNewRecordSize(byte* base, size_t offs);
00471
00481 size_t convertRecord(byte* dst, byte* src, size_t offs);
00482
00493 int sizeWithoutOneField(dbFieldDescriptor* field,
00494 byte* base, size_t& size);
00495
00505 size_t copyRecordExceptOneField(dbFieldDescriptor* field,
00506 byte* dst, byte* src, size_t offs);
00507
00508
00509 enum StoreMode {
00510 Insert,
00511 Update,
00512 Import
00513 };
00514
00525 size_t storeRecordFields(byte* dst, byte* src, size_t offs, StoreMode mode);
00526
00534 void markUpdatedFields(byte* dst, byte* src);
00535
00543 void markUpdatedFields2(byte* dst, byte* src);
00544
00552 void fetchRecordFields(byte* dst, byte* src);
00553
00559 dbFieldDescriptor* findSymbol(const char_t* name);
00560
00566 dbFieldDescriptor* find(const char_t* name);
00567
00572 dbFieldDescriptor* getFirstComponent() {
00573 return components;
00574 }
00575
00580 dbFieldDescriptor* getNextComponent(dbFieldDescriptor* field) {
00581 if (field != NULL) {
00582 field = field->next;
00583 if (field == components) {
00584 return NULL;
00585 }
00586 }
00587 return field;
00588 }
00589
00593 dbFieldDescriptor& operator, (dbFieldDescriptor& field) {
00594 dbFieldDescriptor* tail = field.prev;
00595 tail->next = this;
00596 prev->next = &field;
00597 field.prev = prev;
00598 prev = tail;
00599 return *this;
00600 }
00601
00602 void* operator new(size_t size);
00603 void operator delete(void* p);
00604
00608 dbFieldDescriptor& adjustOffsets(size_t offs);
00609
00619 dbFieldDescriptor(char_t const* name, size_t offs, size_t size, int indexType,
00620 char_t const* inverse = NULL,
00621 dbFieldDescriptor* components = NULL);
00622
00627 dbFieldDescriptor(char_t const* name);
00628
00632 ~dbFieldDescriptor();
00633 };
00634
00635
00639 class GIGABASE_DLL_ENTRY dbTableDescriptor {
00640 friend class dbCompiler;
00641 friend class dbDatabase;
00642 friend class dbReplicatedDatabase;
00643 friend class dbTable;
00644 friend class dbAnyCursor;
00645 friend class dbSubSql;
00646 friend class dbParallelQueryContext;
00647 friend class dbServer;
00648 friend class dbSession;
00649 friend class dbAnyContainer;
00650 friend class dbColumnBinding;
00651 friend class dbFieldDescriptor;
00652 friend class dbSelection;
00653 friend class dbTableIterator;
00654 friend class dbCLI;
00655 friend class dbFileTransactionLogger;
00656
00657 protected:
00661 dbTableDescriptor* next;
00662 static dbTableDescriptor* chain;
00663 static dbMutex* chainMutex;
00664
00668 dbTableDescriptor* nextDbTable;
00669
00673 char_t* name;
00674
00678 oid_t tableId;
00679
00683 dbFieldDescriptor* columns;
00684
00688 dbFieldDescriptor* hashedFields;
00689
00693 dbFieldDescriptor* indexedFields;
00694
00698 dbFieldDescriptor* inverseFields;
00699
00703 dbFieldDescriptor* firstField;
00704
00708 dbFieldDescriptor** nextFieldLink;
00709
00713 dbDatabase* db;
00714
00718 bool fixedDatabase;
00719
00723 bool isStatic;
00724
00730 dbTableDescriptor* cloneOf;
00731
00735 size_t appSize;
00736
00740 size_t fixedSize;
00741
00745 size_t nFields;
00746
00750 size_t nColumns;
00751
00755 oid_t firstRow;
00756
00760 oid_t lastRow;
00761
00765 size_t nRows;
00766
00770 int4 autoincrementCount;
00771
00775 dbTableDescriptor* nextBatch;
00776
00780 bool isInBatch;
00781
00785 dbSelection batch;
00786
00790 int transactionId;
00791
00792
00796 int attr;
00797
00801 typedef dbFieldDescriptor* (*describeFunc)();
00802 describeFunc describeComponentsFunc;
00803
00807 dbTableDescriptor* collisionChain;
00808
00812 size_t totalNamesLength();
00813
00827 void calculateFieldsAttributes(dbFieldDescriptor* fieldsList,
00828 char_t const* prefix, int offs,
00829 int indexMask, int& attr,
00830 size_t& dbsAlignment, size_t& appAlignment);
00831
00840 dbFieldDescriptor* buildFieldsList(dbTable* table, char_t const* prefix,
00841 int prefixLen, int& attr);
00845 dbTableDescriptor* clone();
00846
00847 public:
00851 static int initialAutoincrementCount;
00852
00853
00857 dbTableDescriptor* getNextTable() {
00858 return nextDbTable;
00859 }
00860
00864 dbFieldDescriptor* findSymbol(char_t const* name);
00865
00869 dbFieldDescriptor* find(char_t const* name);
00870
00875 dbFieldDescriptor* getFirstField() {
00876 return columns;
00877 }
00878
00883 int getLastValueOfAutoincrementCount() const {
00884 return autoincrementCount;
00885 }
00886
00892 dbFieldDescriptor* getNextField(dbFieldDescriptor* field) {
00893 if (field != NULL) {
00894 field = field->next;
00895 if (field == columns) {
00896 return NULL;
00897 }
00898 }
00899 return field;
00900 }
00901
00905 char_t* getName() {
00906 return name;
00907 }
00908
00912 size_t size() {
00913 return appSize;
00914 }
00915
00919 oid_t getId() {
00920 return tableId;
00921 }
00922
00930 bool equal(dbTable* table, bool ignoreIndices = false);
00931
00942 bool match(dbTable* table, bool confirmDeleteColumns, bool preserveExistedIndices, bool isEmpty);
00943
00949 bool checkRelationship();
00950
00955 dbDatabase* getDatabase() { return db; }
00956
00961 void storeInDatabase(dbTable* table);
00962
00967 void setFlags();
00968
00969 static dbMutex& getChainMutex();
00970 void link();
00971 void unlink();
00972
00976 static void cleanup();
00977
00978
00983 dbTableDescriptor(dbTable* table);
00984
00993 dbTableDescriptor(char_t const* tableName,
00994 dbDatabase* db,
00995 size_t objSize,
00996 describeFunc func,
00997 dbTableDescriptor* original = NULL);
00998
01002 ~dbTableDescriptor();
01003 };
01004
01008 struct dbVarying {
01009 nat4 size;
01010 int4 offs;
01011 };
01012
01016 struct dbField {
01017 enum FieldTypes {
01018 tpBool,
01019 tpInt1,
01020 tpInt2,
01021 tpInt4,
01022 tpInt8,
01023 tpReal4,
01024 tpReal8,
01025 tpString,
01026 tpReference,
01027 tpArray,
01028 tpMethodBool,
01029 tpMethodInt1,
01030 tpMethodInt2,
01031 tpMethodInt4,
01032 tpMethodInt8,
01033 tpMethodReal4,
01034 tpMethodReal8,
01035 tpMethodString,
01036 tpMethodReference,
01037 tpStructure,
01038 tpRawBinary,
01039 tpStdString,
01040 tpMfcString,
01041 tpRectangle,
01042 tpUnknown
01043 };
01044
01048 dbVarying name;
01049
01053 dbVarying tableName;
01054
01058 dbVarying inverse;
01059
01063 #ifdef OLD_FIELD_DESCRIPTOR_FORMAT
01064 int4 type;
01065 #else
01066 #if BYTE_ORDER == BIG_ENDIAN
01067 int4 flags : 24;
01068 int4 type : 8;
01069 #else
01070 int4 type : 8;
01071 int4 flags : 24;
01072 #endif
01073 #endif
01074
01078 int4 offset;
01079
01083 nat4 size;
01084
01088 oid_t hashTable;
01089
01093 oid_t bTree;
01094 };
01095
01096
01100 class dbRecord {
01101 public:
01105 nat4 size;
01106
01110 oid_t next;
01111
01115 oid_t prev;
01116 };
01117
01118
01122 class dbTable : public dbRecord {
01123 public:
01127 dbVarying name;
01128
01132 dbVarying fields;
01133
01137 nat4 fixedSize;
01138
01142 nat4 nRows;
01143
01147 nat4 nColumns;
01148
01152 oid_t firstRow;
01153
01157 oid_t lastRow;
01158 #ifdef AUTOINCREMENT_SUPPORT
01159
01162 nat4 count;
01163 #endif
01164 };
01165
01166 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
01167 {
01168 fd->type = fd->appType = dbField::tpRawBinary;
01169 fd->alignment = 1;
01170 fd->comparator = comparator;
01171 return fd;
01172 }
01173
01174 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&, int1 defaultValue = 0)
01175 {
01176 fd->type = fd->appType = dbField::tpInt1;
01177 fd->defaultValue.Int1 = defaultValue;
01178 return fd;
01179 }
01180 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&, int2 defaultValue = 0)
01181 {
01182 fd->type = fd->appType = dbField::tpInt2;
01183 fd->defaultValue.Int2 = defaultValue;
01184 return fd;
01185 }
01186 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&, int4 defaultValue = 0)
01187 {
01188 fd->type = fd->appType = dbField::tpInt4;
01189 fd->defaultValue.Int4 = defaultValue;
01190 return fd;
01191 }
01192 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&, db_int8 defaultValue = 0)
01193 {
01194 fd->type = fd->appType = dbField::tpInt8;
01195 fd->defaultValue.Db_Int8 = defaultValue;
01196 return fd;
01197 }
01198 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&, nat1 defaultValue = 0)
01199 {
01200 fd->type = fd->appType = dbField::tpInt1;
01201 fd->defaultValue.Int1 = defaultValue;
01202 return fd;
01203 }
01204 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&, nat2 defaultValue = 0)
01205 {
01206 fd->type = fd->appType = dbField::tpInt2;
01207 fd->defaultValue.Int2 = defaultValue;
01208 return fd;
01209 }
01210 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&, nat4 defaultValue = 0)
01211 {
01212 fd->type = fd->appType = dbField::tpInt4;
01213 fd->defaultValue.Int4 = defaultValue;
01214 return fd;
01215 }
01216 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&, nat8 defaultValue = 0)
01217 {
01218 fd->type = fd->appType = dbField::tpInt8;
01219 fd->defaultValue.Db_Int8 = defaultValue;
01220 return fd;
01221 }
01222
01223 #if SIZEOF_LONG != 8
01224 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&, long defaultValue = 0)
01225 {
01226 fd->type = fd->appType = sizeof(long) == 4 ? dbField::tpInt4 : dbField::tpInt8;
01227 if (sizeof(long) == 4) fd->defaultValue.Int4 = defaultValue;
01228 else fd->defaultValue.Db_Int8 = defaultValue;
01229 return fd;
01230 }
01231 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&, unsigned long defaultValue = 0)
01232 {
01233 fd->type = fd->appType = sizeof(long) == 4 ? dbField::tpInt4 : dbField::tpInt8;
01234 if (sizeof(long) == 4) fd->defaultValue.Int4 = defaultValue;
01235 else fd->defaultValue.Db_Int8 = defaultValue;
01236 return fd;
01237 }
01238 #endif
01239
01240 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&, bool defaultValue = false)
01241 {
01242 fd->type = fd->appType = dbField::tpBool;
01243 fd->defaultValue.Bool = defaultValue;
01244 return fd;
01245 }
01246 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&, real4 defaultValue = 0.0)
01247 {
01248 fd->type = fd->appType = dbField::tpReal4;
01249 fd->defaultValue.Real4 = defaultValue;
01250 return fd;
01251 }
01252 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&, real8 defaultValue = 0.0)
01253 {
01254 fd->type = fd->appType = dbField::tpReal8;
01255 fd->defaultValue.Real8 = defaultValue;
01256 return fd;
01257 }
01258 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, rectangle&)
01259 {
01260 fd->type = fd->appType = dbField::tpRectangle;
01261 fd->alignment = sizeof(coord_t);
01262 return fd;
01263 }
01264
01265 #ifdef USE_STD_STRING
01266 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, STD_STRING&)
01267 {
01268 fd->type = dbField::tpString;
01269 fd->appType = dbField::tpStdString;
01270 fd->dbsSize = sizeof(dbVarying);
01271 fd->alignment = 4;
01272 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01273 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01274 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01275 return fd;
01276 }
01277 #endif
01278 #ifdef USE_MFC_STRING
01279 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, MFC_STRING&)
01280 {
01281 fd->type = dbField::tpString;
01282 fd->appType = dbField::tpMfcString;
01283 fd->dbsSize = sizeof(dbVarying);
01284 fd->alignment = 4;
01285 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01286 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01287 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01288 return fd;
01289 }
01290 #endif
01291
01292 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t const*&)
01293 {
01294 fd->type = fd->appType = dbField::tpString;
01295 fd->dbsSize = sizeof(dbVarying);
01296 fd->alignment = 4;
01297 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01298 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01299 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01300 return fd;
01301 }
01302 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t*&)
01303 {
01304 fd->type = fd->appType = dbField::tpString;
01305 fd->dbsSize = sizeof(dbVarying);
01306 fd->alignment = 4;
01307 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01308 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01309 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01310 return fd;
01311 }
01312
01313
01314 template<class T>
01315 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x)
01316 {
01317 fd->type = fd->appType = dbField::tpStructure;
01318 fd->components = x.dbDescribeComponents(fd);
01319 return fd;
01320 }
01321
01322
01326 class GIGABASE_DLL_ENTRY dbAnyMethodTrampoline {
01327 public:
01328 dbFieldDescriptor* cls;
01329
01335 virtual void invoke(byte* data, void* result) = 0;
01336
01343 virtual dbAnyMethodTrampoline* optimize() = 0;
01344
01349 dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01350
01354 virtual~dbAnyMethodTrampoline();
01355
01356 void* operator new(size_t size);
01357 void operator delete(void* p);
01358 };
01359
01360 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || defined(__HP_aCC) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x510 && __SUNPRO_CC_COMPAT == 5)
01361
01364 template<class T, class R>
01365 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01366 public:
01367 typedef R (T::*mfunc)();
01368
01369 mfunc method;
01370 dbFieldDescriptor* cls;
01371 bool optimized;
01372
01373 void invoke(byte* data, void* result) {
01374 if (optimized) {
01375 *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01376 } else {
01377 T rec;
01378 this->cls->components->fetchRecordFields((byte*)&rec, data);
01379 *(R*)result = (rec.*method)();
01380 }
01381 }
01382 dbAnyMethodTrampoline* optimize() {
01383 optimized = true;
01384 return this;
01385 }
01386
01387 dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01388 : dbAnyMethodTrampoline(fd)
01389 {
01390 this->method = f;
01391 this->cls = fd;
01392 this->optimized = false;
01393 }
01394 };
01395
01396 #else
01397
01401 template<class T, class R>
01402 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01403 public:
01404 typedef R (T::*mfunc)();
01405 mfunc method;
01406
01407 void invoke(byte* data, void* result) {
01408 T rec;
01409 this->cls->components->fetchRecordFields((byte*)&rec, data);
01410 *(R*)result = (rec.*method)();
01411 }
01412 dbAnyMethodTrampoline* optimize();
01413
01414 dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01415 : dbAnyMethodTrampoline(fd), method(f) {}
01416 };
01417
01418 template<class T, class R>
01419 class dbMethodFastTrampoline : public dbAnyMethodTrampoline {
01420 typedef R (T::*mfunc)();
01421 mfunc method;
01422 public:
01423 dbAnyMethodTrampoline* optimize() {
01424 return this;
01425 }
01426 void invoke(byte* data, void* result) {
01427 *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01428 }
01429 dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt)
01430 : dbAnyMethodTrampoline(mt->cls), method(mt->method) {
01431 delete mt;
01432 }
01433 };
01434
01435 template<class T, class R>
01436 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() {
01437 return new dbMethodFastTrampoline<T,R>(this);
01438 }
01439
01440 #endif
01441 template<class T, class R>
01442 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)())
01443 {
01444 R ret;
01445 dbDescribeField(fd, ret);
01446 assert(fd->type <= dbField::tpReference);
01447 fd->appType = fd->type += dbField::tpMethodBool;
01448 fd->method = new dbMethodTrampoline<T,R>(fd, p);
01449 return fd;
01450 }
01451
01452 END_GIGABASE_NAMESPACE
01453
01454 #endif
01455
01456