00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef DBASTOREABLE_H
00010 #define DBASTOREABLE_H
00011
00014 #include <string>
00015 #include "dba/database.h"
00016 #include "dba/archiveexception.h"
00017 #include "dba/storeablefilter.h"
00018 #include "dba/defs.h"
00019
00020 namespace dba {
00021
00025 class dbaDLLEXPORT MemberEntryBase {
00026 public:
00032 MemberEntryBase(const char* pMemberName, int pMemberOffset);
00036 int getMemberOffset() const;
00040 const char* getMemberName() const;
00044 void setMemberOffset(int pNewOffset);
00045 private:
00046 const char* mMemberName;
00047 int mMemberOffset;
00048 };
00049
00050 template <typename T, typename M>
00051 class MemberTableBase {
00052 public:
00053 MemberTableBase(const char* pTableName);
00054 const char* getTableName() const;
00055 int getClassOffset() const;
00056 void setClassOffset(int pOffset);
00057 const T* getNextTable() const;
00058 M* getMembers() const;
00059 void addMember(M* pMember);
00060 void setNextTable(const T* pTable);
00061 ~MemberTableBase();
00062 private:
00063 int mClassOffset;
00064 const char* mTableName;
00065 const T* mNextTable;
00066 M* mMembers;
00067 };
00068
00069 class StoreTable;
00070 class ColTable;
00071
00075 class dbaDLLEXPORT StoreTableMember : public MemberEntryBase {
00076 public:
00085 StoreTableMember(StoreTable* pOwner, const char* pMemberName, int pMemberOffset, StoreableFilterBase* pFilter, int pDatabaseType);
00090 void setFilterOwner(bool pFlag);
00095 void setTable(StoreTable* pOwner);
00100 StoreableFilterBase* getFilter();
00105 int getDatabaseType();
00110 StoreTableMember* getNextMember() const;
00115 void setNextMember(StoreTableMember* pMember);
00119 ~StoreTableMember();
00120 private:
00121 StoreableFilterBase* mFilter;
00122 bool mFilterOwner;
00123 int mDatabaseType;
00124 StoreTableMember* mNextMember;
00125 };
00126
00130 class dbaDLLEXPORT StoreTable : public MemberTableBase<StoreTable,StoreTableMember> {
00131 public:
00132 StoreTable(const char* pTableName) : MemberTableBase<StoreTable,StoreTableMember>(pTableName) {};
00133 ~StoreTable() {};
00134 private:
00135 };
00136
00137 class CollectionFilterBase;
00138 class Storeable;
00139
00143 class dbaDLLEXPORT ColMemberEntry : public MemberEntryBase {
00144 public:
00145 ColMemberEntry(ColTable* pOwner, const char* pMemberName, int pMemberOffset, CollectionFilterBase* pFilter, const char* pFKeyName);
00146 ColMemberEntry(ColTable* pOwner, const char* pMemberName, int pMemberOffset, CollectionFilterBase* pFilter, const char* pFKeyName, const char* pTableName, id pRelationName);
00147 const char* getTableName() const;
00148 const char* getFKeyName() const;
00149 id getRelationId() const;
00150 ColMemberEntry* getNextMember() const;
00151 void setNextMember(ColMemberEntry* pNextMember);
00152 CollectionFilterBase* getFilter();
00153 ~ColMemberEntry();
00154 private:
00155 const char* mTableName;
00156 const char* mFKeyName;
00157 id mRelationId;
00158 CollectionFilterBase* mFilter;
00159 ColMemberEntry* mNextMember;
00160 };
00161
00165 class dbaDLLEXPORT ColTable : public MemberTableBase<ColTable,ColMemberEntry> {
00166 public:
00167 ColTable(const char* pName) : MemberTableBase<ColTable,ColMemberEntry>(pName) {};
00168 ~ColTable() {};
00169 };
00170
00174 class dbaDLLEXPORT StoreTableList {
00175 public:
00176 StoreTableList();
00177 std::set<StoreTable*> mStoreTables;
00178 std::set<ColTable*> mColTables;
00179 ~StoreTableList();
00180 };
00181
00187 #define DECLARE_STORE_TABLE() public: \
00188 virtual const dba::StoreTable* st_getTable(); \
00189 virtual const dba::ColTable* st_getColTable(); \
00190 protected: \
00191 static dba::StoreTable* st_table;\
00192 static dba::ColTable* st_ColTable;\
00193 private:\
00194 void st_createTables();
00195
00206 #define BEGIN_STORE_TABLE(Class,parent,table) \
00207 dba::StoreTable* Class::st_table = NULL; \
00208 dba::ColTable* Class::st_ColTable = NULL; \
00209 const dba::StoreTable* \
00210 Class::st_getTable() { \
00211 if (Class::st_table == NULL) \
00212 st_createTables(); \
00213 return Class::st_table; \
00214 };\
00215 const dba::ColTable* \
00216 Class::st_getColTable() { \
00217 if (Class::st_ColTable == NULL) \
00218 st_createTables(); \
00219 return Class::st_ColTable; \
00220 }; \
00221 void \
00222 Class::st_createTables() { \
00223 st_table = new dba::StoreTable(table); \
00224 st_table->setClassOffset( (char*)(Class*)dba::Storeable::dba_pointer_place - (char*)dba_pointer_place ); \
00225 st_table->setNextTable(parent::st_getTable()); \
00226 sStoreTableList.mStoreTables.insert(st_table); \
00227 st_ColTable = new dba::ColTable(table); \
00228 st_ColTable->setClassOffset( (char*)(Class*)dba::Storeable::dba_pointer_place - (char*)dba_pointer_place ); \
00229 st_ColTable->setNextTable(parent::st_getColTable()); \
00230 sStoreTableList.mColTables.insert(st_ColTable);
00231
00239 #define BIND_STR(member,filter_class,field) \
00240 new dba::StoreTableMember(st_table,field,&reinterpret_cast<char &>(member) - (char*)this,new filter_class(member),dba::Database::STRING);
00241
00249 #define BIND_INT(member,filter_class,field) \
00250 new dba::StoreTableMember(st_table,field,&reinterpret_cast<char &>(member) - (char*)this,new filter_class(member),dba::Database::INTEGER);
00251
00259 #define BIND_FLT(member,filter_class,field) \
00260 new dba::StoreTableMember(st_table,field,&reinterpret_cast<char &>(member) - (char*)this,new filter_class(member),dba::Database::FLOAT);
00261
00269 #define BIND_DAT(member,filter_class,field) \
00270 new dba::StoreTableMember(st_table,field,&reinterpret_cast<char &>(member) - (char*)this,new filter_class(member),dba::Database::DATE);
00271
00280 #define BIND_COL(member,filter_class,fkname) \
00281 new dba::ColMemberEntry(st_ColTable,NULL,&reinterpret_cast<char &>(member) - (char*)this,new filter_class(member),fkname);
00282
00295 #define BIND_CLA(member,filter_class,fkname,coll_id,table_name) \
00296 new dba::ColMemberEntry(st_ColTable,NULL,&reinterpret_cast<char &>(member) - (char*)this,new filter_class(member),fkname,table_name,coll_id);
00297
00303 #define BIND_STB(member) \
00304 { \
00305 const dba::StoreTable* table = member.st_getTable(); \
00306 while(table != NULL) { \
00307 const dba::StoreTableMember* entry = table->getMembers(); \
00308 while(entry != NULL) { \
00309 dba::StoreTableMember* tmp = new dba::StoreTableMember(*entry); \
00310 tmp->setFilterOwner(false); \
00311 tmp->setMemberOffset(tmp->getMemberOffset() + ((char*)&(member) - (char*)this)); \
00312 st_table->addMember(tmp); \
00313 entry = entry->getNextMember(); \
00314 }; \
00315 table = table->getNextTable(); \
00316 }; \
00317 };
00318
00322 #define END_STORE_TABLE() \
00323 };
00324
00325 class Archive;
00326
00333 class dbaDLLEXPORT Storeable {
00334 friend class Stream;
00335 public:
00348 class StidLocker {
00349 public:
00355 StidLocker(Storeable& pObj, bool pPreserveState = false)
00356 : mObj(pObj)
00357 {
00358 mObj.lockStid(pPreserveState);
00359 };
00363 ~StidLocker() {
00364 mObj.unlockStid();
00365 };
00366 private:
00367 StidLocker(const StidLocker&);
00368 StidLocker& operator=(const StidLocker&);
00369 Storeable& mObj;
00370 };
00374 template <typename T> bool setMember(T& pMember, const T& pNevVal);
00379 static const id InvalidId = 0;
00383 static const Storeable* const dba_pointer_place;
00384
00389 static StoreTableList sStoreTableList;
00390
00392 typedef enum {
00394 NEW,
00396 CHANGED,
00398 DELETED,
00400 OK
00401 } stState;
00406 Storeable(id pId = InvalidId);
00411 Storeable(const Storeable& pObj);
00416 Storeable& operator=(const Storeable& pObj);
00422 void setId(id pId);
00427 void setChanged();
00432 const char* getRootTable();
00436 virtual void setNew();
00441 void setDeleted();
00446 stState getState() const;
00451 void setOk();
00456 virtual void lockStid(bool pPreserveState);
00460 virtual void unlockStid();
00505 virtual void setState(stState pState);
00510 id getId() const;
00515 bool isDeleted() const;
00520 bool isChanged() const;
00525 bool isNew() const;
00530 bool isOk() const;
00534 virtual ~Storeable();
00535 protected:
00539 typedef enum {
00540 UNLOCKED = 0,
00541 LOCKED = 1,
00542 LOCKED_PRESERVE_STATE = 2
00543 } lock_state;
00547 virtual const StoreTable* st_getTable();
00551 virtual const ColTable* st_getColTable();
00556 void preserveIdAssigment(const Storeable& pObj);
00561 void normalAssigment(const Storeable& pObj);
00565 id mId;
00569 int mStoredTables;
00573 int countTables();
00577 stState mStoreState;
00581 lock_state mIdLocked;
00582 };
00583
00590 template <typename T>
00591 bool
00592 Storeable::setMember(T& pMember, const T& pNewVal) {
00593 if (pMember == pNewVal)
00594 return false;
00595 pMember = pNewVal;
00596 setChanged();
00597 return true;
00598 };
00599
00600
00601 template <typename T, typename M>
00602 MemberTableBase<T,M>::MemberTableBase(const char* pTableName)
00603 : mTableName(pTableName),
00604 mClassOffset(0),
00605 mNextTable(NULL),
00606 mMembers(NULL)
00607 {};
00608
00609 template <typename T, typename M>
00610 const char*
00611 MemberTableBase<T,M>::getTableName() const {
00612 return mTableName;
00613 };
00614
00615 template <typename T, typename M>
00616 int
00617 MemberTableBase<T,M>::getClassOffset() const {
00618 return mClassOffset;
00619 };
00620
00621 template <typename T, typename M>
00622 void
00623 MemberTableBase<T,M>::setClassOffset(int pOffset) {
00624 mClassOffset = pOffset;
00625 };
00626
00627 template <typename T, typename M>
00628 const T*
00629 MemberTableBase<T,M>::getNextTable() const {
00630 return mNextTable;
00631 };
00632
00633 template <typename T, typename M>
00634 M*
00635 MemberTableBase<T,M>::getMembers() const {
00636 return mMembers;
00637 };
00638
00639 template <typename T, typename M>
00640 void
00641 MemberTableBase<T,M>::setNextTable(const T* pTable) {
00642 mNextTable = pTable;
00643 };
00644
00645 template <typename T, typename M>
00646 void
00647 MemberTableBase<T,M>::addMember(M* pMember) {
00648 pMember->setNextMember(mMembers);
00649 mMembers = pMember;
00650 };
00651
00652 template <typename T, typename M>
00653 MemberTableBase<T,M>::~MemberTableBase() {
00654 while (mMembers != NULL) {
00655 M* next = mMembers->getNextMember();
00656 delete mMembers;
00657 mMembers = next;
00658 };
00659 };
00660
00661 };
00662
00663
00664 #endif