1 /*
2  * Copyright (C) 2010 Emweb bv, Herent, Belgium.
3  *
4  * See the LICENSE file for terms of use.
5  */
6 
7 /*****
8  * This file is part of the Wt::Dbo tutorial:
9  * http://www.webtoolkit.eu/wt/doc/tutorial/dbo/tutorial.html
10  *****/
11 
12 /*****
13  * Dbo tutorial section 7.4
14  *  Specifying a natural primary key that is also a foreign key
15  *****/
16 
17 #include <Wt/Dbo/Dbo.h>
18 #include <Wt/Dbo/backend/Sqlite3.h>
19 
20 namespace dbo = Wt::Dbo;
21 
22 struct Coordinate {
23   int x, y;
24 
CoordinateCoordinate25   Coordinate()
26     : x(-1), y(-1) { }
27 
CoordinateCoordinate28   Coordinate(int an_x, int an_y)
29     : x(an_x), y(an_y) { }
30 
31   bool operator== (const Coordinate& other) const {
32     return x == other.x && y == other.y;
33   }
34 
35   bool operator< (const Coordinate& other) const {
36     if (x < other.x)
37       return true;
38     else if (x == other.x)
39       return y < other.y;
40     else
41       return false;
42   }
43 };
44 
45 std::ostream& operator<< (std::ostream& o, const Coordinate& c)
46 {
47   return o << "(" << c.x << ", " << c.y << ")";
48 }
49 
50 namespace Wt {
51   namespace Dbo {
52 
53     template <class Action>
54     void field(Action& action, Coordinate& coordinate, const std::string& name,
55 	       int /*size*/ = -1)
56     {
57       field(action, coordinate.x, name + "_x");
58       field(action, coordinate.y, name + "_y");
59     }
60   }
61 }
62 
63 class GeoTag;
64 
65 namespace Wt {
66   namespace Dbo {
67 
68     template<>
69     struct dbo_traits<GeoTag> : public dbo_default_traits
70     {
71       typedef Coordinate IdType;
72       static IdType invalidId() { return Coordinate(); }
73       static const char *surrogateIdField() { return 0; }
74     };
75   }
76 }
77 
78 class GeoTag {
79 public:
80   Coordinate  position;
81   std::string name;
82 
83   template <class Action>
84   void persist(Action& a)
85   {
86     dbo::id(a, position, "position");
87     dbo::field(a, name, "name");
88   }
89 };
90 
91 void run()
92 {
93   /*
94    * Setup a session, would typically be done once at application startup.
95    */
96   std::unique_ptr<dbo::backend::Sqlite3> sqlite3(new dbo::backend::Sqlite3(":memory:"));
97   sqlite3->setProperty("show-queries", "true");
98   dbo::Session session;
99   session.setConnection(std::move(sqlite3));
100 
101   session.mapClass<GeoTag>("geotag");
102 
103   /*
104    * Try to create the schema (will fail if already exists).
105    */
106   session.createTables();
107 
108   {
109     dbo::Transaction transaction(session);
110 
111     std::unique_ptr<GeoTag> tag{new GeoTag()};
112     tag->position = Coordinate(5091, 315);
113     tag->name = "Oekene";
114 
115     dbo::ptr<GeoTag> tagPtr = session.add(std::move(tag));
116 
117     transaction.commit();
118 
119     std::cerr << tagPtr.id() << std::endl;
120   }
121 }
122 
123 int main(int argc, char **argv)
124 {
125   run();
126 }
127