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/annotations.d.
8  *
9  * This module contains declarations of DStruct Annotations - User Defined Attribues used to markup D classes and their properties for ORM.
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.annotations;
16 
17 
18 
19 /**
20  * @Transient - mark class or field as transient, to not generate DStruct persistence metadata for it.
21  * Use this annotation in cases when field you won't persist will be considered as persistent otherwise.
22  */
23 struct Transient {
24     immutable bool dummy;
25 }
26 
27 
28 /** 
29  * Class level annotations.
30  * 
31  * DStruct maps values of some class to DB table. This class is referred as Entity.
32  * 
33  * Entity contains one or more properties - which are usually mapped to DB table columns.
34  */
35 
36 /**
37  * Mark class with this annotation if you want to make it persistable.
38  * @Entity or @Entity() - marks class as entity, using class name as entity name.
39  */
40 struct Entity {
41 	//immutable string name;
42     immutable bool dummy;
43     //	this(string name) { this.name = name; }
44 }
45 
46 /**
47  * @Embeddable or @Embeddable() - mark class as entity which can only be embedded into other entities, and doesn't have separate columns.
48  * Columns for each of Embeddable entity properties will be placed into parent entity's table, where this embeddable entity is embedded
49  */
50 struct Embeddable {
51 	immutable bool dummy;
52 //	this(bool enabled) {}
53 }
54 
55 /**
56  * Use to specify table name for entity.
57  * @Table("table_name") - specifies table name to store entity in, different from default generated.
58  * If this annotation not present, table name will be autogenerated as lowercase entity name with conversion of 
59  * CamelCaseEntityName to camel_case_entity_name.
60  */
61 struct Table {
62 	immutable string name;
63 //	this(string name) { this.name = name; }
64 }
65 
66 /** 
67  * Property level annotations.
68  * 
69  * Supported simple types for properties (may be stored in single DB table column):
70  *     byte, short, int, long, ubyte, ushort, uint, ulong, float, double, byte[], ubyte[], string, DateTime, Date, TimeOfDay
71  * 
72  * Other possible types of properties:
73  *     Embeddable entity class -- implementation in progress
74  *     Entity class Lazy!class -- ManyToOne or OneToOne relation
75  *     Entity class array or LazyCollection!class -- collection for OneToMany or ManyToMany
76  * 
77  * Supported kinds of property holders:
78  *     field -- just public field
79  *     @property -- D language read/write property
80  *     getField()/setField(x) method pair
81  * 
82  * Each entity property has a name. It's derived from field, @property or getter/setter name.
83  * For field and D @property - name of field of property is used as name of entity property, with first letter lowercased.
84  * For getters/setters, get/set/is prefix is removed from mothod name, and the rest with lowercased first letter is used as property name.
85  */
86 
87 /**
88  * Mark property as simple persistent property (must be of one of simple types).
89  * 
90  * @Column or @Column() - simple column, with name derived from field/property name.
91  * @Column("column_name") - simple column with specified name.
92  * @Column("column_name", field_length) - simple column with specified name and length (e.g. for varchar).
93  * @Column(field_length) - simple column with specified length; column name will be autogenerated
94  * 
95  * If column name is not specified, lowercased name of property with _ delimited camelCase words is used as column name.
96  * Field name camelCasePropertyName will be converted to camel_case_property_name column name.
97  */
98 struct Column {
99 	immutable string name;
100 	immutable int length;
101 //	this(string name) { this.name = name; }
102 //	this(string name, int length) { this.name = name; this.length = length; }
103 //	this(int length) { this.length = length; }
104 }
105 
106 /**
107  * @Id or @Id() - mark simple property as primary key of entity.
108  */
109 struct Id {
110 	immutable bool dummy;
111 }
112 
113 /**
114  * @Generated or @Generated() - mark simple property as column as server generated value (e.g. AUTO INCREMENT field)
115  */
116 struct Generated {
117 	immutable bool dummy;
118 }
119 
120 /**
121  * @Generator(code) - specify code to call for generation of simple property key value (will be inserted into definition Variant function(Connection conn, PropertyInfo prop) { return Variant($code); }
122  */
123 struct Generator {
124     string code;
125 }
126 
127 /// standard generator - generates random UUID - for use as @Generator() annotation parameter. Don't forget to import std.uuid
128 const string UUID_GENERATOR = "std.uuid.randomUUID().toString()";
129 
130 /**
131  * @NotNull or @NotNull() - mark entity property as not null (NULLs are not allowed in DB)
132  * If neither @NotNull nor @Null specified, nullability will be derived from field type (e.g. NotNull for int, long; Null for string, byte[], Nullable!int)
133  */
134 struct NotNull {
135 	immutable bool dummy;
136 }
137 
138 /**
139  * @Null or @Null() - mark entity property as nullable (NULLs are allowed in DB)
140  * If neither @NotNull nor @Null specified, nullability will be derived from field type (e.g. NotNull for int, long; Null for string, byte[], Nullable!int)
141  */
142 struct Null {
143 	immutable bool dummy;
144 }
145 
146 /**
147  * @UniqueKey or @UniqueKey() - mark entity property as unique (UNIQUE INDEX will be created for this column, with autogenerated index name)
148  * @UniqueKey(indexName) - mark entity property as unique (UNIQUE INDEX will be created for this column, with specified index name)
149  * For multiple column unique constraints, use Entity level annotations (TODO).
150  */
151 struct UniqueKey {
152     immutable string name;
153 }
154 
155 
156 /**
157  * @OneToOne(propertyName) - referenced object uses one-to-one relation, propertyName is referenced entity's property to join with current entity's primary key.
158  * @OneToOne or @OneToOne() - referenced object uses one-to-one relation, requires additional @JoinColumn annotation to specify foreign key column in current entity to join with current entity's primary key.
159  */
160 struct OneToOne {
161 	immutable string name;
162 //	this(string referencedPropertyName) { this.name = name; }
163 }
164 
165 /**
166  * @ManyToOne or @ManyToOne() - referenced object uses many-to-one relation, requires additional @JoinColumn annotation to specify foreign key column in current entity to join with current entity's primary key.
167  */
168 struct ManyToOne {
169     immutable bool dummy;
170 }
171 
172 /**
173  * @JoinColumn(columnName) - specify foreign key column name to join other entity's by its primary key - for @OneToOne relation.
174  * @JoinColumn or @JoinColumn() - foreign key column name will be autogenerated from referenced entity name, with _fk suffix.
175  * This annotation is mandatory if property has @OneToOne annotation w/o parameter or @ManyToOne annotation
176  */
177 struct JoinColumn {
178 	immutable string name;
179 //	this(string columnName) { this.name = name; }
180 }
181 
182 /**
183  * @OneToMany(referencedProperty) - referenced objects use one-to-many relation, requires additional property name in target entity which has specified foreign key column and ManyToOne to join with current entity's primary key.
184  */
185 struct OneToMany {
186     immutable string name;
187 }
188 
189 /**
190  * @ManyToMany(joinTableName, joinColumn1, joinColumn2) - referenced objects use many-to-many relation via additional join table, requires additional parameters to specify join table to implement relation, and fk columns to referene this and related entities.
191  * @ManyToMany or @ManyToMany() - referenced objects use many-to-many relation via additional join table, will autogenerate join table name to implement relation, and fk column names to referene this and related entities.
192  */
193 struct ManyToMany {
194     immutable string joinTableName;
195     immutable string joinColumn1;
196     immutable string joinColumn2;
197 }
198 
199 
200 unittest {
201 
202 	@Entity
203 	@Table("user")
204 	class User {
205 
206 		@Id @Generated
207 		@Column("id")
208 		int id;
209 
210 		@Column("name")
211 		string name;
212 	}
213 
214 }