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