123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- /*
- * Copyright (C) 2014 Emweb bvba, Herent, Belgium.
- *
- * See the LICENSE file for terms of use.
- */
- #ifdef SQLITE3
- #include <boost/test/unit_test.hpp>
- #include <Wt/Dbo/Dbo>
- #include <Wt/Dbo/Json>
- #include <Wt/Dbo/backend/Sqlite3>
- namespace dbo = Wt::Dbo;
- namespace JsonDboTest {
- class Post;
- class User;
- class NestedThing;
- class Post {
- public:
- dbo::ptr<User> user;
- dbo::weak_ptr<NestedThing> nestedThing;
- std::string title;
- std::string body;
- template<class Action>
- void persist(Action& a)
- {
- dbo::belongsTo(a, user, "user");
- dbo::hasOne(a, nestedThing, "post");
- dbo::field(a, title, "title");
- dbo::field(a, body, "body");
- }
- };
- class NestedThing {
- public:
- int one;
- int two;
- int three;
- dbo::ptr<Post> post;
- template<class Action>
- void persist(Action& a)
- {
- dbo::field(a, one, "one");
- dbo::field(a, two, "two");
- dbo::field(a, three, "three");
- dbo::belongsTo(a, post, "post");
- }
- };
- class Empty {
- public:
- template<class Action>
- void persist(Action& a)
- {
- }
- };
- class Settings {
- public:
- std::string theme;
- dbo::ptr<User> user;
- template<class Action>
- void persist(Action& a)
- {
- dbo::field(a, theme, "theme");
- dbo::belongsTo(a, user);
- }
- };
- class User {
- public:
- enum Role {
- Visitor = 0,
- Admin = 1,
- Alien = 42
- };
- std::string name;
- std::string password;
- Role role;
- int karma;
- dbo::collection< dbo::ptr<Post> > posts;
- dbo::weak_ptr<Settings> settings;
- template<class Action>
- void persist(Action& a)
- {
- dbo::field(a, name, "name");
- dbo::field(a, password, "password");
- dbo::field(a, role, "role");
- dbo::field(a, karma, "karma");
- dbo::hasMany(a, posts, dbo::ManyToOne, "user");
- dbo::hasOne(a, settings);
- }
- };
- class HasSurrogate {
- public:
- std::string foo;
- template<class Action>
- void persist(Action& a)
- {
- dbo::field(a, foo, "foo");
- }
- };
- class HasNatural {
- public:
- std::string myNaturalId;
- std::string foo;
- template<class Action>
- void persist(Action& a)
- {
- dbo::id(a, myNaturalId, "natural_id", 20);
- dbo::field(a, foo, "foo");
- }
- };
- struct Coordinate {
- int x, y;
- Coordinate()
- : x(-1), y(-1) { }
- Coordinate(int an_x, int an_y)
- : x(an_x), y(an_y) { }
- bool operator== (const Coordinate& other) const {
- return x == other.x && y == other.y;
- }
-
- bool operator< (const Coordinate& other) const {
- if (x < other.x)
- return true;
- else if (x == other.x)
- return y < other.y;
- else
- return false;
- }
- };
- std::ostream& operator<< (std::ostream& o, const Coordinate& c)
- {
- return o << "{" << c.x << ", " << c.y << ")";
- }
- class HasCoordinateId;
- }
- namespace Wt {
- namespace Dbo {
- template <class Action>
- void field(Action& action, JsonDboTest::Coordinate& coordinate, const std::string& name, int size = -1)
- {
- field(action, coordinate.x, name + "_x");
- field(action, coordinate.y, name + "_y");
- }
- template<>
- struct dbo_traits<JsonDboTest::HasSurrogate> : public dbo_default_traits {
- static const char *surrogateIdField() { return "alternate_id"; }
- };
- template<>
- struct dbo_traits<JsonDboTest::HasNatural> : public dbo_default_traits {
- typedef std::string IdType;
- static IdType invalidId() {
- return std::string();
- }
- static const char *surrogateIdField() { return 0; }
- };
- template<>
- struct dbo_traits<JsonDboTest::HasCoordinateId> : public dbo_default_traits
- {
- typedef JsonDboTest::Coordinate IdType;
- static IdType invalidId() { return JsonDboTest::Coordinate(); }
- static const char *surrogateIdField() { return 0; }
- };
- }
- }
- namespace JsonDboTest {
- class HasCoordinateId {
- public:
- Coordinate position;
- std::string name;
- template <class Action>
- void persist(Action& a)
- {
- dbo::id(a, position, "position");
- dbo::field(a, name, "name");
- }
- };
- struct JsonDboFixture
- {
- JsonDboFixture()
- {
- static bool logged = false;
- if (!logged) {
- std::cerr << "JsonTest.C created a Sqlite3 connector" << std::endl;
- logged = true;
- }
- dbo::backend::Sqlite3 *sqlite3 = new dbo::backend::Sqlite3(":memory:");
- connection_ = sqlite3;
- session_ = new dbo::Session();
- session_->setConnection(*connection_);
- session_->mapClass<User>("user");
- session_->mapClass<Post>("post");
- session_->mapClass<NestedThing>("nestedThing");
- session_->mapClass<Settings>("settings");
- session_->mapClass<Empty>("empty");
- session_->mapClass<HasSurrogate>("hasSurrogate");
- session_->mapClass<HasNatural>("hasNatural");
- session_->mapClass<HasCoordinateId>("hasCoordinateId");
- session_->createTables();
- }
- ~JsonDboFixture()
- {
- session_->dropTables();
- delete session_;
- delete connection_;
- }
- dbo::SqlConnection *connection_;
- dbo::Session *session_;
- };
- BOOST_AUTO_TEST_CASE( dbo_json_empty_test )
- {
- JsonDboFixture f;
- dbo::Session &session = *f.session_;
- {
- dbo::Transaction transaction(session);
- Empty *empty = new Empty();
-
- std::stringstream ss;
- dbo::jsonSerialize(*empty, ss);
- BOOST_REQUIRE_EQUAL(ss.str(), "{}");
- dbo::ptr<Empty> emptyPtr = session.add(empty);
- }
- dbo::Transaction transaction(session);
- dbo::collection<dbo::ptr<Empty> > empties = session.find<Empty>();
- std::stringstream ss;
- dbo::jsonSerialize(empties.front(), ss);
- BOOST_REQUIRE_EQUAL(ss.str(), "{\"id\":1}");
- }
- BOOST_AUTO_TEST_CASE( dbo_json_empty_and_null_test )
- {
- JsonDboFixture f;
- dbo::Session &session = *f.session_;
- {
- dbo::Transaction transaction(session);
- User *user = new User();
- user->name = "John";
- user->password = "Something";
- user->role = User::Alien;
- user->karma = 13;
- session.add(user);
- }
- dbo::Transaction transaction(session);
- dbo::ptr<User> user = session.find<User>().where("name = ?").bind("John");
- std::string expected = "{\"id\":1,\"name\":\"John\",\"password\":\"Something\",\"role\":42,"
- "\"karma\":13,\"posts_user\":[],\"settings_\":null}";
-
- std::stringstream ss;
- jsonSerialize(user, ss);
- BOOST_REQUIRE_EQUAL(ss.str(), expected);
- }
- BOOST_AUTO_TEST_CASE( dbo_json_surrogate_id_test )
- {
- JsonDboFixture f;
- dbo::Session &session = *f.session_;
- dbo::ptr<HasSurrogate> hasSurrogate;
- {
- dbo::Transaction transaction(session);
- hasSurrogate = session.add(new HasSurrogate());
- hasSurrogate.modify()->foo = "bar";
- }
- dbo::Transaction transaction(session);
- std::string expected = "{\"alternate_id\":1,\"foo\":\"bar\"}";
- std::stringstream ss;
- jsonSerialize(hasSurrogate, ss);
- BOOST_REQUIRE_EQUAL(ss.str(), expected);
- }
- BOOST_AUTO_TEST_CASE( dbo_json_natural_id_test )
- {
- JsonDboFixture f;
- dbo::Session &session = *f.session_;
- dbo::ptr<HasNatural> hasNatural;
- {
- dbo::Transaction transaction(session);
- hasNatural = session.add(new HasNatural());
- hasNatural.modify()->myNaturalId = "Nature!";
- hasNatural.modify()->foo = "bar";
- }
- dbo::Transaction transaction(session);
- std::string expected = "{\"natural_id\":\"Nature!\",\"foo\":\"bar\"}";
- std::stringstream ss;
- jsonSerialize(hasNatural, ss);
- BOOST_REQUIRE_EQUAL(ss.str(), expected);
- }
- BOOST_AUTO_TEST_CASE( dbo_json_composite_key_test )
- {
- JsonDboFixture f;
- dbo::Session &session = *f.session_;
- dbo::ptr<HasCoordinateId> hasCoordinateId;
- {
- dbo::Transaction transaction(session);
- hasCoordinateId = session.add(new HasCoordinateId());
- hasCoordinateId.modify()->position = Coordinate(3, 4);
- hasCoordinateId.modify()->name = "foo";
- }
-
- dbo::Transaction transaction(session);
- std::string expected = "{\"position_x\":3,\"position_y\":4,\"name\":\"foo\"}";
- std::stringstream ss;
- jsonSerialize(hasCoordinateId, ss);
- BOOST_REQUIRE_EQUAL(ss.str(), expected);
- }
- BOOST_AUTO_TEST_CASE( dbo_json_complex_test )
- {
- JsonDboFixture f;
- dbo::Session &session = *f.session_;
- {
- dbo::Transaction transaction(session);
- User *user = new User();
- user->name = "Joe";
- user->password = "Secret";
- user->role = User::Visitor;
- user->karma = 13;
- dbo::ptr<User> userPtr = session.add(user);
- }
- dbo::ptr<Post> post;
- dbo::ptr<NestedThing> nestedThing;
- {
- dbo::Transaction transaction(session);
- dbo::ptr<User> joe = session.find<User>().where("name = ?").bind("Joe");
- post = session.add(new Post());
- post.modify()->user = joe;
- post.modify()->body = "Lorem ipsum dolor sit amet \"escape me\" something something";
- post.modify()->title = "Hello";
- nestedThing = session.add(new NestedThing());
- nestedThing.modify()->one = 1;
- nestedThing.modify()->two = 2;
- nestedThing.modify()->three = 3;
- nestedThing.modify()->post = post;
- }
- {
- dbo::Transaction transaction(session);
- dbo::ptr<User> joe = session.find<User>().where("name = ?").bind("Joe");
- dbo::ptr<Settings> settings = session.add(new Settings());
- settings.modify()->theme = "fancy-pink";
- joe.modify()->settings = settings;
- }
- dbo::Transaction transaction(session);
- dbo::ptr<User> joe = session.find<User>().where("name = ?").bind("Joe");
- std::stringstream ss;
- dbo::jsonSerialize(joe, ss);
- std::string joeString = "{\"id\":1,\"name\":\"Joe\",\"password\":\"Secret\",\"role\":0,\"karma\":13,"
- "\"posts_user\":[{\"id\":1,\"user\":1,\"nestedThing_post\":{\"id\":1,\"one\":1,\"two\":2,\"three\":3,\"post\":1},"
- "\"title\":\"Hello\",\"body\":\"Lorem ipsum dolor sit amet \\\"escape me\\\" something something\"}],"
- "\"settings_\":{\"id\":1,\"theme\":\"fancy-pink\",\"user\":1}}";
- BOOST_REQUIRE_EQUAL(ss.str(), joeString);
- }
- }
- #endif
|