1 /**
2  * DStruct - Object-Relation Mapping for D programming language, with interface similar to Hibernate. 
3  * 
4  * Hibernate documentation can be found here:
5  * $(LINK http://hibernate.org/docs)$(BR)
6  * 
7  * Source file dstruct/tests.d.
8  *
9  * This module contains unit tests for functional testing on real DB.
10  * 
11  * Copyright: Copyright 2013
12  * License:   $(LINK www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
13  * Author:   Vadim Lopatin
14  */
15 module dstruct.tests;
16 
17 import std.algorithm;
18 import std.conv;
19 import std.stdio;
20 import std.datetime;
21 import std.typecons;
22 import std.exception;
23 import std.variant;
24 
25 import dstruct.core;
26 
27 version (unittest)
28 {
29 
30     //@Entity
31     @Table("users")  // to override table name - "users" instead of default "user"
32     class User
33     {
34 
35         //@Generated
36         long id;
37 
38         string name;
39 
40         // property column
41         private long _flags;
42         @Null // override NotNull which is inferred from long type
43         @property void flags(long v)
44         {
45             _flags = v;
46         }
47 
48         @property ref long flags()
49         {
50             return _flags;
51         }
52 
53         // getter/setter property
54         string comment;
55         // @Column -- not mandatory, will be deduced
56         @Null // override default nullability of string with @Null (instead of using String)
57         @Column(null, 1024)  // override default length, autogenerate column name)
58         string getComment()
59         {
60             return comment;
61         }
62 
63         void setComment(string v)
64         {
65             comment = v;
66         }
67 
68         //@ManyToOne -- not mandatory, will be deduced
69         //@JoinColumn("customer_fk")
70         Customer customer;
71 
72         @ManyToMany LazyCollection!Role roles;
73 
74         override string toString()
75         {
76             return "id=" ~ to!string(id) ~ ", name=" ~ name ~ ", flags=" ~ to!string(
77                     flags) ~ ", comment=" ~ comment ~ ", customerId=" ~ (customer is null
78                     ? "NULL" : customer.toString());
79         }
80 
81     }
82 
83     //@Entity
84     @Table("customers")  // to override table name - "customers" instead of default "customer"
85     class Customer
86     {
87         //@Generated
88         int id;
89         // @Column -- not mandatory, will be deduced
90         string name;
91 
92         // deduced as @Embedded automatically
93         Address address;
94 
95         //@ManyToOne -- not mandatory, will be deduced
96         //@JoinColumn("account_type_fk")
97         Lazy!AccountType accountType;
98 
99         //        @OneToMany("customer")
100         //        LazyCollection!User users;
101 
102         //@OneToMany("customer") -- not mandatory, will be deduced
103         private User[] _users;
104         @property User[] users()
105         {
106             return _users;
107         }
108 
109         @property void users(User[] value)
110         {
111             _users = value;
112         }
113 
114         this()
115         {
116             address = new Address();
117         }
118 
119         override string toString()
120         {
121             return "id=" ~ to!string(id) ~ ", name=" ~ name ~ ", address=" ~ address.toString();
122         }
123     }
124 
125     static assert(isEmbeddedObjectMember!(Customer, "address"));
126 
127     @Embeddable class Address
128     {
129         String zip;
130         String city;
131         String streetAddress;
132         @Transient // mark field with @Transient to avoid creating column for it
133         string someNonPersistentField;
134 
135         override string toString()
136         {
137             return " zip=" ~ zip ~ ", city=" ~ city ~ ", streetAddress=" ~ streetAddress;
138         }
139     }
140 
141     @Entity // need to have at least one annotation to import automatically from module
142     class AccountType
143     {
144         //@Generated
145         int id;
146         string name;
147     }
148 
149     //@Entity 
150     class Role
151     {
152         //@Generated
153         int id;
154         string name;
155         @ManyToMany LazyCollection!User users;
156     }
157 
158     //@Entity
159     //@Table("t1")
160     class T1
161     {
162         //@Id 
163         //@Generated
164         int id;
165 
166         //@NotNull 
167         @UniqueKey string name;
168 
169         // property column
170         private long _flags;
171         // @Column -- not mandatory, will be deduced
172         @property long flags()
173         {
174             return _flags;
175         }
176 
177         @property void flags(long v)
178         {
179             _flags = v;
180         }
181 
182         // getter/setter property
183         private string comment;
184         // @Column -- not mandatory, will be deduced
185         @Null string getComment()
186         {
187             return comment;
188         }
189 
190         void setComment(string v)
191         {
192             comment = v;
193         }
194 
195         override string toString()
196         {
197             return "id=" ~ to!string(id) ~ ", name=" ~ name ~ ", flags=" ~ to!string(
198                     flags) ~ ", comment=" ~ comment;
199         }
200     }
201 
202     @Entity static class GeneratorTest
203     {
204         //@Generator("std.uuid.randomUUID().toString()")
205         @Generator(UUID_GENERATOR)
206         string id;
207         string name;
208     }
209 
210     @Entity static class TypeTest
211     {
212         //@Generated
213         int id;
214         string string_field;
215         String nullable_string_field;
216         byte byte_field;
217         short short_field;
218         int int_field;
219         long long_field;
220         ubyte ubyte_field;
221         ushort ushort_field;
222         ulong ulong_field;
223         DateTime datetime_field;
224         Date date_field;
225         TimeOfDay time_field;
226         Byte nullable_byte_field;
227         Short nullable_short_field;
228         Int nullable_int_field;
229         Long nullable_long_field;
230         Ubyte nullable_ubyte_field;
231         Ushort nullable_ushort_field;
232         Ulong nullable_ulong_field;
233         NullableDateTime nullable_datetime_field;
234         NullableDate nullable_date_field;
235         NullableTimeOfDay nullable_time_field;
236         float float_field;
237         double double_field;
238         Float nullable_float_field;
239         Double nullable_double_field;
240         byte[] byte_array_field;
241         ubyte[] ubyte_array_field;
242     }
243 
244 }
245 
246 version (unittest)
247 {
248     // for testing of Embeddable
249     @Embeddable class EMName
250     {
251         string firstName;
252         string lastName;
253     }
254 
255     //@Entity 
256     class EMUser
257     {
258         //@Id @Generated
259         //@Column
260         int id;
261 
262         // deduced as @Embedded automatically
263         EMName userName;
264     }
265 
266     // for testing of Embeddable
267     //@Entity
268     class Person
269     {
270         //@Id
271         int id;
272 
273         // @Column @NotNull        
274         string firstName;
275         // @Column @NotNull        
276         string lastName;
277 
278         @NotNull @OneToOne @JoinColumn("more_info_fk")
279         MoreInfo moreInfo;
280     }
281 
282     //@Entity
283     @Table("person_info")
284     class MoreInfo
285     {
286         //@Id @Generated
287         int id;
288         // @Column 
289         long flags;
290         @OneToOne("moreInfo")
291         Person person;
292         @OneToOne("personInfo")
293         EvenMoreInfo evenMore;
294     }
295 
296     //@Entity
297     @Table("person_info2")
298     class EvenMoreInfo
299     {
300         //@Id @Generated
301         int id;
302         //@Column 
303         long flags;
304         @OneToOne @JoinColumn("person_info_fk")
305         MoreInfo personInfo;
306     }
307 
308 }