Changeset 136
- Timestamp:
- 05/21/08 22:38:41 (8 months ago)
- Files:
-
- trunk/dba/dba/ostream.cpp (modified) (2 diffs)
- trunk/dba/dba/ostream.h (modified) (3 diffs)
- trunk/dba/dba/storeable.h (modified) (2 diffs)
- trunk/dba/dba/xmlostream.cpp (modified) (2 diffs)
- trunk/dba/dba/xmlostream.h (modified) (2 diffs)
- trunk/dba/docs/dba.doxyfile (modified) (1 diff)
- trunk/dba/test/main.cpp (modified) (2 diffs)
- trunk/dba/test/testobject.h (modified) (10 diffs)
- trunk/dba/test/utils.cpp (modified) (1 diff)
- trunk/dba/test/xmltestcase.cpp (modified) (1 diff)
- trunk/dba/test/xmltestcase.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/dba/dba/ostream.cpp
r115 r136 45 45 46 46 bool 47 OStream::putChild(Storeable* pObject, ColMemberEntry& pMember, CollectionFilterBase& pFilter, const char* pTableName) { 48 bool ret = false; 49 bool was_changed = false; 50 //ref data contains id - old fk_value pairs 51 id rel_id = pMember.getRelationId(); 52 std::vector<id> ids = loadRefData(pTableName, pMember.getFKeyName(), rel_id, pObject->getId()); 53 //if object is deleted forget about storing children and 54 //start deleting them 55 if (!pObject->isDeleted()) { 56 std::auto_ptr<CollectionFilterIterator> iterator(pFilter.createIterator()); 57 //bind foreign key to object table 58 id fk_value = pObject->getId(); 59 //iterate through collection and store all changed objects 60 //deleted objects are erased with their all children recursively 61 while(iterator->hasNext()) { 62 //this is current instance of storeable object from BIND_COL list 63 //we cast away const for update and update will alter 64 //Storeable member fields. Because of this collection order 65 //should not be determined by any of Storeable field. 66 Storeable& toStore = (Storeable&)(iterator->get()); 67 //if object is deleted we just ignore it 68 //its id is on ids list and this object will be deleted 69 //with rest of objects loaded from database and not on this list 70 if (!toStore.isDeleted()) { 71 //if object is not on list then it is new or 72 //was moved from another parent 73 std::vector<id>::iterator it = std::find(ids.begin(),ids.end(),toStore.getId()); 74 if (it == ids.end()) { 75 toStore.setChanged(); 76 } else { 77 //prevent erasing object and its children by eraseChildren(ids,...) below 78 ids.erase(it); 79 }; 80 bind(pTableName,pMember.getFKeyName(), new Int(fk_value), Database::INTEGER); 81 if (rel_id != Storeable::InvalidId) 82 bind(pTableName,"dba_coll_id", new Int(rel_id), Database::INTEGER); 83 open(pTableName); 84 if (toStore.isNew()) { 85 was_changed = store(&toStore); 86 } else if (toStore.isChanged()) { 87 was_changed = update(&toStore); 88 }; 89 if (was_changed) 90 makeOk(pObject); 91 unbind(pTableName,pMember.getFKeyName()); 92 if (rel_id != Storeable::InvalidId) 93 unbind(pTableName,"dba_coll_id"); 94 setRootTable(NULL); 95 was_changed = putChildren(&toStore); 96 if (!ret) ret = was_changed; 97 }; 98 iterator->moveForward(); 99 }; 100 }; 101 //there are unknown child objects loaded from database. 102 //synthesize instance for them and delete them with 103 //their children recursively. 104 if (!ids.empty()) { 105 Storeable& for_table = pFilter.create(); 106 was_changed = eraseChildren(ids,for_table,pTableName); 107 if (!ret) ret = was_changed; 108 }; 109 return ret; 110 }; 111 112 bool 47 113 OStream::putChildren(Storeable* pObject) { 48 114 bool ret = false; 49 bool was_changed = false;50 115 const ColTable* table = getColTable(*pObject); 51 116 while(table != NULL) { … … 60 125 filter.updateRef((char*)pObject + member->getMemberOffset()); 61 126 const char* obj_table = member->getTableName(); 62 //ref data contains id - old fk_value pairs 63 id rel_id = member->getRelationId(); 64 std::vector<id> ids = loadRefData(obj_table, member->getFKeyName(), rel_id, pObject->getId()); 65 //if object is deleted forget about storing children and 66 //start deleting them 67 if (!pObject->isDeleted()) { 68 std::auto_ptr<CollectionFilterIterator> iterator(filter.createIterator()); 69 //bind foreign key to object table 70 id fk_value = pObject->getId(); 71 //iterate through collection and store all changed objects 72 //deleted objects are erased with their all children recursively 73 while(iterator->hasNext()) { 74 //this is current instance of storeable object from BIND_COL list 75 //we cast away const for update and update will alter 76 //Storeable member fields. Because of this collection order 77 //should not be determined by any of Storeable field. 78 Storeable& toStore = (Storeable&)(iterator->get()); 79 //if object is deleted we just ignore it 80 //its id is on ids list and this object will be deleted 81 //with rest of objects loaded from database and not on this list 82 if (!toStore.isDeleted()) { 83 //if object is not on list then it is new or 84 //was moved from another parent 85 std::vector<id>::iterator it = std::find(ids.begin(),ids.end(),toStore.getId()); 86 if (it == ids.end()) { 87 toStore.setChanged(); 88 } else { 89 //prevent erasing object and its children by eraseChildren(ids,...) below 90 ids.erase(it); 91 }; 92 bind(obj_table,member->getFKeyName(), new Int(fk_value), Database::INTEGER); 93 if (rel_id != Storeable::InvalidId) 94 bind(obj_table,"dba_coll_id", new Int(rel_id), Database::INTEGER); 95 open(obj_table); 96 if (toStore.isNew()) { 97 was_changed = store(&toStore); 98 } else if (toStore.isChanged()) { 99 was_changed = update(&toStore); 100 }; 101 if (was_changed) 102 makeOk(pObject); 103 unbind(obj_table,member->getFKeyName()); 104 if (rel_id != Storeable::InvalidId) 105 unbind(obj_table,"dba_coll_id"); 106 setRootTable(NULL); 107 was_changed = putChildren(&toStore); 108 if (!ret) ret = was_changed; 109 }; 110 iterator->moveForward(); 111 }; 112 }; 113 //there are unknown child objects loaded from database. 114 //synthesize instance for them and delete them with 115 //their children recursively. 116 if (!ids.empty()) { 117 Storeable& for_table = filter.create(); 118 was_changed = eraseChildren(ids,for_table,obj_table); 119 if (!ret) ret = was_changed; 120 }; 127 //call archive specific store alghoritm 128 bool was_changed = putChild(pObject, *member, filter, obj_table); 129 if (!ret) ret = was_changed; 121 130 //move forward in loop 122 131 member = member->getNextMember(); trunk/dba/dba/ostream.h
r115 r136 49 49 @param pObject object to store 50 50 */ 51 bool put(Storeable* pObject);51 virtual bool put(Storeable* pObject); 52 52 /** 53 53 Prepare stream to put Storeable objects in it. If there is problem with object store then dba::DataException is thrown. … … 67 67 */ 68 68 virtual ~OStream() {}; 69 protected: 70 /** 71 Default implementation for BIND_COL store that works on data stored in relations and 72 linked using foreign keys. For data formats that are not layed out in this kind of structures 73 you should override this method providing different alghoritm 74 @param pObject pointer to root object 75 @param pMember member from collection table 76 @param pFilter filter that should be used to create instance of object 77 @param pTableName name of root relation 78 @return true if at least one subobject object was stored in archive, false otherwise 79 */ 80 virtual bool putChild(Storeable* pObject, ColMemberEntry& pMember, CollectionFilterBase& pFilter, const char* pTableName); 81 /** 82 Store all Storeable objects on sublists listed as BIND_COL in store table 83 @param pObject object that will be examined 84 */ 85 virtual bool putChildren(Storeable* pObject); 86 /** 87 Erase all objects that are related to Storeable pObj object using 88 BIND_COL entries in store table. 89 @param pRefData list of object identifiers 90 @param pObj instance of object that will be erased. Used for extractiin ColTable recursively 91 @param pRootTableName altered name of root store table of pObj or NULL if root table was not altered 92 */ 93 virtual bool eraseChildren(const std::vector<id>& pRefData, Storeable& pObj, const char* pRootTableName); 69 94 private: 70 95 /** … … 99 124 */ 100 125 virtual bool deleteRefData(const std::vector<id>& pIds, const char* pTableName); 101 /**102 Store all Storeable objects on sublists listed as BIND_COL in store table103 @param pObject object that will be examined104 */105 bool putChildren(Storeable* pObject);106 /**107 Erase all objects that are related to Storeable pObj object using108 BIND_COL entries in store table.109 @param pRefData list of object identifiers110 @param pObj instance of object that will be erased. Used for extractiin ColTable recursively111 @param pRootTableName altered name of root store table of pObj or NULL if root table was not altered112 */113 bool eraseChildren(const std::vector<id>& pRefData, Storeable& pObj, const char* pRootTableName);114 126 }; 115 127 trunk/dba/dba/storeable.h
r73 r136 20 20 namespace dba { 21 21 22 /** 23 Base class for store and collection table members 24 */ 22 25 class dbaDLLEXPORT MemberEntryBase { 23 26 public: 27 /**@internal 28 Constructor - for internal use only 29 @param pMemberName name of relation field for member 30 @param pMemberOffset number of bytes from 'this' to first byte of member field in class 31 */ 24 32 MemberEntryBase(const char* pMemberName, int pMemberOffset); 33 /**@internal 34 Get number of bytes from this to first byte of member field 35 */ 25 36 int getMemberOffset() const; 37 /** 38 Get name of relation where class member is stored 39 */ 26 40 const char* getMemberName() const; 41 /**@internal 42 set in BIND_* macros - for internal use only 43 */ 27 44 void setMemberOffset(int pNewOffset); 28 45 private: … … 53 70 class ColTable; 54 71 55 /** @internal56 single entry in store table72 /** 73 %Single entry in store table 57 74 */ 58 75 class dbaDLLEXPORT StoreTableMember : public MemberEntryBase { 59 76 public: 77 /**@internal 78 Constructor - used by BIND_* macros - for internal use only 79 @param pOwner store table that owns this member 80 @param pMemberName name of relation field for member 81 @param pMemberOffset number of bytes from 'this' to first byte of member field in class 82 @param pFilter instance of storeable filter for data conversion 83 @param pDatabaseType type of archive data (Database::StoreType enum value) 84 */ 60 85 StoreTableMember(StoreTable* pOwner, const char* pMemberName, int pMemberOffset, StoreableFilterBase* pFilter, int pDatabaseType); 86 /**@internal 87 used by BIND_* macros - for internal use only 88 @param pFlag true if member owns passed pointer 89 */ 61 90 void setFilterOwner(bool pFlag); 91 /**@internal 92 Add member to store table - for internal use only 93 @param pOwner store table where member should be added 94 */ 62 95 void setTable(StoreTable* pOwner); 63 96 /** 97 Get pointer to filter assigned to member 98 @return pointer to filter instance 99 */ 64 100 StoreableFilterBase* getFilter(); 101 /**@internal 102 Get archive data type 103 @return one of Database::StoreType enum values 104 */ 65 105 int getDatabaseType(); 106 /**@internal 107 Get next member from store table member list 108 @return pointer to next member or NULL if not found 109 */ 66 110 StoreTableMember* getNextMember() const; 111 /**@internal 112 Set next member - for internal use only 113 @param pMember new value of mNextMember field 114 */ 67 115 void setNextMember(StoreTableMember* pMember); 116 /** 117 Deletes mFilter instance if mFilterOwner is true 118 */ 68 119 ~StoreTableMember(); 69 120 private: trunk/dba/dba/xmlostream.cpp
r133 r136 12 12 #include "xmlostream.h" 13 13 #include "conversion.h" 14 #include "collectionfilter.h" 14 15 15 16 namespace dba { … … 99 100 }; 100 101 xmlAddChild(mParentNode, node); 102 //set new parent node for storing subobjects 103 mParentNode = node; 101 104 }; 102 105 103 106 std::vector<id> 104 107 XMLOStream::loadRefData(const char* pTable, const char* pFkName, id pCollId, id pId) { 105 //TODO 108 //not used 109 return std::vector<id>(); 106 110 }; 107 111 108 112 bool 109 113 XMLOStream::deleteRefData(const std::vector<id>& pIds, const char* pTableName) { 110 //TODO 114 //not used 115 return false; 116 }; 117 118 bool 119 XMLOStream::putChildren(Storeable* pObject) { 120 bool ret = OStream::putChildren(pObject); 121 //parent node was set in store() to point to valid parent object 122 //in hierarchy. After storing all children we have to reset it back to 123 //parent of pObject node 124 mParentNode = mParentNode->parent; 125 if (mParentNode == NULL) 126 throw DatabaseException("Internal error: parent node is NULL"); 127 }; 128 129 bool 130 XMLOStream::putChild(Storeable* pObject, ColMemberEntry& pMember, CollectionFilterBase& pFilter, const char* pTableName) { 131 bool was_changed = false; 132 bool ret = false; 133 if (!pObject->isDeleted()) { 134 std::auto_ptr<CollectionFilterIterator> iterator(pFilter.createIterator()); 135 while(iterator->hasNext()) { 136 Storeable& toStore = (Storeable&)(iterator->get()); 137 if (!toStore.isDeleted()) { 138 was_changed = store(&toStore); 139 if (!ret) ret = was_changed; 140 }; 141 iterator->moveForward(); 142 }; 143 }; 144 return ret; 111 145 }; 112 146 trunk/dba/dba/xmlostream.h
r133 r136 30 30 virtual void commit() { throw APIException("commit() not supported for XML format"); } 31 31 virtual void rollback() { throw APIException("rollback() not supported for XML format"); } 32 virtual ~XMLOStream(); 33 protected: 32 34 virtual void assignId(Storeable* pObject) throw (Exception); 33 35 virtual bool erase(Storeable* pObject); … … 35 37 virtual bool store(Storeable* pObject); 36 38 virtual bool isCollectionFilterSupported() const { return true; }; 39 virtual bool putChild(Storeable* pObject, ColMemberEntry& pMember, CollectionFilterBase& pFilter, const char* pTableName); 40 virtual bool putChildren(Storeable* pObject); 37 41 virtual std::vector<id> loadRefData(const char* pTable, const char* pFkName, id pCollId, id pId); 38 42 virtual bool deleteRefData(const std::vector<id>& pIds, const char* pTableName); 39 virtual ~XMLOStream();40 43 private: 41 44 xmlNodePtr mParentNode; trunk/dba/docs/dba.doxyfile
r97 r136 22 22 EXTRACT_LOCAL_CLASSES = YES 23 23 EXTRACT_LOCAL_METHODS = NO 24 HIDE_UNDOC_MEMBERS = NO24 HIDE_UNDOC_MEMBERS = YES 25 25 HIDE_UNDOC_CLASSES = YES 26 26 HIDE_FRIEND_COMPOUNDS = YES trunk/dba/test/main.cpp
r133 r136 144 144 CppUnit::BriefTestProgressListener listener; 145 145 runner.eventManager().addListener(&listener); 146 //runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );146 runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() ); 147 147 //runner.addTest(new CppUnit::TestCaller<SQLite3SQLArchiveTestCase>("debug_test",&SQLite3SQLArchiveTestCase::sqlError)); 148 148 //runner.addTest(new CppUnit::TestCaller<PostgresSQLArchiveTestCase>("debug_test",&PostgresSQLArchiveTestCase::sqlError)); … … 151 151 //runner.addTest(new CppUnit::TestCaller<SQLite3SQLArchiveTestCase>("debug_test",&SQLite3SQLArchiveTestCase::transactions_rollback)); 152 152 //runner.addTest(dba_tests::XMLTestCase::suite()); 153 runner.addTest(new CppUnit::TestCaller<dba_tests::XMLTestCase>("debug_test",&dba_tests::XMLTestCase::varLoad));153 //runner.addTest(new CppUnit::TestCaller<dba_tests::XMLTestCase>("debug_test",&dba_tests::XMLTestCase::sublist_one)); 154 154 //runner.addTest(new CppUnit::TestCaller<OdbcPluginTestCase>("debug_test",&OdbcPluginTestCase::dbConnection)); 155 155 //runner.addTest(new CppUnit::TestCaller<PostgresSQLArchiveTestCase>("debug_test",&PostgresSQLArchiveTestCase::sqlError)); trunk/dba/test/testobject.h
r48 r136 245 245 */ 246 246 AgregatedObject(bool pVersion = false) 247 : mObject(7,7.7,"7",Utils::get Now())247 : mObject(7,7.7,"7",Utils::getDate(2008,1,1,0,0,0)) 248 248 { 249 249 if (pVersion) { 250 250 mInt = 77; 251 251 } else { 252 mObject = TestObject(3,3.3,"333",Utils::get Now(-33));252 mObject = TestObject(3,3.3,"333",Utils::getDate(2008,1,33,0,0,0)); 253 253 mInt = 33; 254 254 }; … … 310 310 { 311 311 for (int i=0; i < pChildrenCount; i++) { 312 mList.push_back(TestObject(i,i,"test_object",Utils::get Now(i)));312 mList.push_back(TestObject(i,i,"test_object",Utils::getDate(2008,1,i+1,0,0,0))); 313 313 }; 314 314 }; … … 338 338 { 339 339 for (int i=0; i < pChildrenCount; i++) { 340 mList.insert(TestObject(i,i,"test_object",Utils::get Now(i)));340 mList.insert(TestObject(i,i,"test_object",Utils::getDate(2008,1,i+1,0,0,0))); 341 341 }; 342 342 }; … … 366 366 { 367 367 for (int i=0; i < pChildrenCount; i++) { 368 mList.insert(TestObject(i,i,"test_object",Utils::get Now(i)));368 mList.insert(TestObject(i,i,"test_object",Utils::getDate(2008,1,i+1,0,0,0))); 369 369 }; 370 370 }; … … 394 394 { 395 395 for (int i=0; i < pChildrenCount; i++) { 396 mList.push_back(TestObject(i,i,"test_object",Utils::get Now(i)));396 mList.push_back(TestObject(i,i,"test_object",Utils::getDate(2008,1,i+1,0,0,0))); 397 397 }; 398 398 }; … … 422 422 { 423 423 for (int i=0; i < pChildrenCount; i++) { 424 mList.push_back(TestObject(i,i,"test_object",Utils::get Now(i)));424 mList.push_back(TestObject(i,i,"test_object",Utils::getDate(2008,1,i+1,0,0,0))); 425 425 }; 426 426 }; … … 450 450 { 451 451 for (int i=0; i < pChildrenCount; i++) { 452 mList.push_back(InheritedObject(i,i,"ObjWithInheritedList child",Utils::get Now(i)));452 mList.push_back(InheritedObject(i,i,"ObjWithInheritedList child",Utils::getDate(2008,1,i+1,0,0,0))); 453 453 }; 454 454 }; … … 508 508 TreeObject() {}; 509 509 TreeObject(int pInt, double pDouble, const std::string& pStr) 510 : TestObject(pInt, pDouble, pStr, Utils::get Now())510 : TestObject(pInt, pDouble, pStr, Utils::getDate(2008,1,1,0,0,0)) 511 511 {}; 512 512 bool operator==(const TreeObject& pObj) const { … … 533 533 { 534 534 for (int i=0; i < pChildrenCount; i++) { 535 mList.push_back(NullEmptyTestObject(i,i,"null_test_object",Utils::get Now(i)));535 mList.push_back(NullEmptyTestObject(i,i,"null_test_object",Utils::getDate(2008,1,i+1,0,0,0))); 536 536 }; 537 537 }; … … 559 559 TwoSubobjects(const char* pName) 560 560 : mName(pName), 561 mObj1(TestObject(1,1,"1",Utils::get Now())),562 mObj2(TestObject(2,2,"2",Utils::get Now(1)))561 mObj1(TestObject(1,1,"1",Utils::getDate(2008,1,1,0,0,0))), 562 mObj2(TestObject(2,2,"2",Utils::getDate(2008,1,2,0,0,0))) 563 563 {}; 564 564 bool operator==(const TwoSubobjects& pObj) { trunk/dba/test/utils.cpp
r79 r136 34 34 ret.tm_sec = pSec; 35 35 ret.tm_isdst = -1; 36 //normalize fields 37 mktime(&ret); 36 38 return ret; 37 39 }; trunk/dba/test/xmltestcase.cpp
r133 r136 179 179 }; 180 180 181 void 182 XMLTestCase::sublist_one() { 183 const char* result = 184 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 185 "<dba>\n" 186 " <obj_with_list name=\"sub\">\n" 187 " <test_objects i_value=\"0\" f_value=\"0\" s_value=\"test_object\" d_value=\"2008-01-01Z00:00:00\"/>\n" 188 " </obj_with_list>\n" 189 "</dba>\n"; 190 { 191 dba::XMLArchive ar; 192 unlink("sublist_one.xml"); 193 ar.open("sublist_one.xml"); 194 ObjWithList obj1("sub",1); 195 dba::XMLOStream stream(ar.getOStream()); 196 stream.open(); 197 stream.put(&obj1); 198 } 199 CPPUNIT_ASSERT(compareXML("sublist_one.xml",result)); 200 }; 201 202 181 203 } //namespace trunk/dba/test/xmltestcase.h
r133 r136 33 33 CPPUNIT_TEST(simpleLoad); 34 34 CPPUNIT_TEST(varLoad); 35 CPPUNIT_TEST(sublist_one); 35 36 CPPUNIT_TEST_SUITE_END(); 36 37 public: … … 47 48 void simpleLoad(); 48 49 void varLoad(); 50 void sublist_one(); 49 51 private: 50 52 bool compareXML(const char* pFilename, const char* pData);
