1 module generaltest;
2 
3 import std.typecons;
4 import std.stdio;
5 import std.format;
6 import std.conv;
7 
8 import hibernated.core;
9 
10 import testrunner : BeforeClass, Test, AfterClass, runTests;
11 import hibernatetest : HibernateTest;
12 
13 // Annotations of entity classes
14 @Table( "gebruiker" )
15 class User {
16   long id;
17   string name;
18   int some_field_with_underscore;
19   @ManyToMany // cannot be inferred, requires annotation
20   LazyCollection!Role roles;
21   //@ManyToOne
22   MyGroup group;
23 
24   @OneToMany
25   Address[] addresses;
26 
27   Asset[] assets;
28 
29   override string toString() {
30     return format("{id: %s, name: %s, roles: %s, group: %s}",
31         id, name, roles, group);
32   }
33 }
34 
35 class Role {
36   int id;
37   string name;
38   @ManyToMany // w/o this annotation will be OneToMany by convention
39   LazyCollection!User users;
40 
41   override string toString() {
42     return format("{id: %s, name: %s}", id, name);
43   }
44 }
45 
46 class Address {
47   @Generated @Id int addressId;
48   User user;
49   string street;
50   string town;
51   string country;
52 
53   override string toString() {
54     return format("{id: %s, user: %s, street: %s, town: %s, country: %s}", addressId, user, street, town, country);
55   }
56 }
57 
58 class Asset {
59   @Generated @Id int id;
60   User user;
61   string name;
62 
63   override string toString() {
64     return format("{id: %s, name: %s}", id, name);
65   }
66 }
67 
68 @Entity
69 class MyGroup {
70   long id;
71   string name;
72   @OneToMany
73   LazyCollection!User users;
74 
75   override string toString() {
76     return format("{id: %s, name: %s}", id, name);
77   }
78 }
79 
80 class GeneralTest : HibernateTest {
81   override
82   EntityMetaData buildSchema() {
83     return new SchemaInfoImpl!(User, Role, Address, Asset, MyGroup);
84   }
85 
86   @Test("general test")
87   void generalTest() {
88     // create session
89     Session sess = sessionFactory.openSession();
90     scope(exit) sess.close();
91 
92     // use session to access DB
93 
94     writeln("Querying empty DB");
95     Query q = sess.createQuery("FROM User ORDER BY name");
96     User[] list = q.list!User();
97     writeln("Result size is " ~ to!string(list.length));
98     assert(list.length == 0);
99 
100     // create sample data
101     writeln("Creating sample schema");
102     MyGroup grp1 = new MyGroup();
103     grp1.name = "Group-1";
104     MyGroup grp2 = new MyGroup();
105     grp2.name = "Group-2";
106     MyGroup grp3 = new MyGroup();
107     grp3.name = "Group-3";
108 
109     Role r10 = new Role();
110     r10.name = "role10";
111     Role r11 = new Role();
112     r11.name = "role11";
113 
114     // create a user called Alex with an address and an asset
115     User u10 = new User();
116     u10.name = "Alex";
117     u10.roles = [r10, r11];
118     u10.group = grp3;
119 
120     auto address = new Address();
121     address.street = "Some Street";
122     address.town = "Big Town";
123     address.country = "Alaska";
124     address.user = u10;
125     writefln("Saving Address: %s", address);
126     sess.save(address);
127 
128     u10.addresses = [address];
129 
130     auto asset = new Asset();
131     asset.name = "Something Precious";
132     asset.user = u10;
133     writefln("Saving Asset: %s", asset);
134     sess.save(asset);
135     u10.assets = [asset];
136 
137     User u12 = new User();
138     u12.name = "Arjan";
139     u12.roles = [r10, r11];
140     u12.group = grp2;
141 
142     User u13 = new User();
143     u13.name = "Wessel";
144     u13.roles = [r10, r11];
145     u13.group = grp2;
146 
147     writeln("saving group 1-2-3" );
148     sess.save( grp1 );
149     sess.save( grp2 );
150     sess.save( grp3 );
151 
152     writeln("Saving Role r10: " ~ r10.name);
153     sess.save(r10);
154 
155     writeln("Saving Role r11: " ~ r11.name);
156     sess.save(r11);
157 
158     {
159       writeln("Saving User u10: " ~ u10.name ~ "...");
160       long id = sess.save(u10).get!long;
161       assert(id > 0L);
162       writeln("\tuser saved with id: " ~ to!string(id));
163     }
164 
165     {
166       writeln("Saving User u12: " ~ u12.name ~ "...");
167       long id = sess.save(u12).get!long;
168       assert(id > 0L);
169       writeln("\tuser saved with id: " ~ to!string(id));
170     }
171 
172     {
173       writeln("Saving User u13: " ~ u13.name ~ "...");
174       long id = sess.save(u13).get!long;
175       assert(id > 0L);
176       writeln("\tuser saved with id: " ~ to!string(id));
177     }
178 
179     writeln("Querying User by name 'Alex'...");
180     // load and check data
181     auto qresult = sess.createQuery("FROM User WHERE name=:Name and some_field_with_underscore != 42").setParameter("Name", "Alex");
182     writefln( "\tquery result: %s", qresult.listRows() );
183     User u11 = qresult.uniqueResult!User();
184     writefln("\tChecking fields for User 11 : %s", u11);
185     assert(u11.roles.length == 2);
186     assert(u11.roles[0].name == "role10" || u11.roles.get()[0].name == "role11");
187     assert(u11.roles[1].name == "role10" || u11.roles.get()[1].name == "role11");
188     assert(u11.roles[0].users.length == 3);
189     assert(u11.roles[0].users[0] == u10);
190 
191     assert(u11.addresses.length == 1);
192     assert(u11.addresses[0].street == "Some Street");
193     assert(u11.addresses[0].town == "Big Town");
194     assert(u11.addresses[0].country == "Alaska");
195 
196     assert(u11.assets.length == 1);
197     assert(u11.assets[0].name == "Something Precious");
198 
199     // selecting all from address table should return a row that joins to the user table
200     auto allAddresses = sess.createQuery("FROM Address").list!Address();
201     assert(allAddresses.length == 1);
202     writefln("Found address : %s", allAddresses[0]);
203     assert(allAddresses[0].street == "Some Street");
204     assert(allAddresses[0].user == u11);
205 
206     // selecting all from asset table should return a row that joins to the user table
207     auto allAssets = sess.createQuery("FROM Asset").list!Asset();
208     assert(allAssets.length == 1);
209     writefln("Found asset : %s", allAssets[0]);
210     assert(allAssets[0].name == "Something Precious");
211     assert(allAssets[0].user == u11);
212 
213     // now test something else
214     writeln("Test retrieving users by group... (ManyToOne relationship)");
215     auto qUsersByGroup = sess.createQuery("FROM User WHERE group=:group_id").setParameter("group_id", grp2.id);
216     User[] usersByGroup = qUsersByGroup.list!User();
217     assert(usersByGroup.length == 2); // user 2 and user 2
218 
219     {
220       writeln("Updating User u10 name (from Alex to Alexander)...");
221       u10.name = "Alexander";
222       sess.update(u10);
223 
224       User u = sess.createQuery("FROM User WHERE id=:uid")
225           .setParameter("uid", u10.id)
226           .uniqueResult!User();
227       assert(u.id == u10.id);
228       assert(u.name == "Alexander");
229     }
230 
231     // remove reference
232     //std.algorithm.remove(u11.roles.get(), 0);
233     //sess.update(u11);
234 
235     {
236       auto allUsers = sess.createQuery("FROM User").list!User();
237       assert(allUsers.length == 3); // Should be 3 user nows
238     }
239     writeln("Removing User u11");
240     sess.remove(u11);
241 
242     {
243       auto allUsers = sess.createQuery("FROM User").list!User();
244       assert(allUsers.length == 2); // Should only be 2 users now
245     }
246   }
247 }
248