今天看freshmeat的時候,又發現一個有趣Object Persistent方案。
http://litesql.sourceforge.net/
Features
- C++ wrapper for sqlite
- all the good stuff of sqlite
- light persistence layer with relation support
- automatic database schema creation and upgrading from C++ classes
- small code base: less than 2500 lines of C++
- create complex SQL queries using compile-time checked class API; minimizes need to write SQL query strings
按文檔,做一個Persistent類的步驟如下:
一、繼承 Persistent
class OwnPersistent : public Persistent {};
二、使用宏PERSISTENT_BASE聲明哪些變量需要Persistent
class OwnPersistent : public Persistent {
??? PERSISTENT_BASE(OwnPersistent, 1, name, TEXT);
};
其中,第一個參數是類名,第二個參數表示后面有多少個變量,后面兩個兩個參數為一組,描述每一個變量。
三、可以用RELATIONS宏描述類之間關聯
RELATIONS(object, relnum,
???????? rel1type, rel1from, rel1to, rel1id, rel1bidir, rel1name,
?????????rel2type, rel2from, rel2to, rel2id, rel2bidir, rel2name, ...)
其中的 relntype可以為以下幾種:
OORelation : one-to-one relation
OMRelation : one-to-many relation
MORelation : many-to-one relation
MMRelation : many-to-many relation
relnfrom、relnto是說從哪個類映射到哪個類
relnid是映射關系的編號
relnbidir是指定映射是否雙向(只有當from和to是同一個類的時候可以使用)
relnname映射關系的名字
例如:
class Person : public Persistent {
??? PERSISTENT_BASE(Person, 1, name, TEXT);
??? RELATIONS(Persistent, 3,
????????????? OORelation, Person, Person, 1, false, mother,
????????????? OORelation, Person, Person, 2, false, father,
????????????? MMRelation, Person, Person, 3, true, friends);
};
最后就是聲明cleanUp函數了,這里看得不是很明白,呵呵。
最后的結果就是:
class Person : public Persistent {
??? PERSISTENT_BASE(Person, 1, name, TEXT);
??? RELATIONS(Persistent, 3,
????????????? OORelation, Person, Person, 1, false, mother,
????????????? OORelation, Person, Person, 2, false, father,
????????????? MMRelation, Person, Person, 3, true, friends);
???? virtual void cleanUp() {
???????? mother.flush();
???????? father.flush();
???????? friends.flush();
???? }
};
Person bill(db), bob(db);
bill.name = "Bill";
bill.update();
bob.name = "Bob";
bob.update();
bill.friends.link(bob);
bob.friends.link(bill);
Person bob = bill.friends.fetchOne(Person::name_() == "Bob");
vector billsFriends = bill.friends.fetch();
效果的確有趣。不過沒有仔細看具體實現。按作者自己說難度之一就是實現這種不定參數的宏。