-
Notifications
You must be signed in to change notification settings - Fork 31
/
annotations.d
281 lines (254 loc) · 9.84 KB
/
annotations.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/**
* HibernateD - Object-Relation Mapping for D programming language, with interface similar to Hibernate.
*
* Hibernate documentation can be found here:
* $(LINK http://hibernate.org/docs)$(BR)
*
* Source file hibernated/annotations.d.
*
* This module contains declarations of HibernateD Annotations - User Defined Attribues used to markup D classes and their properties for ORM.
*
* Copyright: Copyright 2013
* License: $(LINK www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Author: Vadim Lopatin
*/
module hibernated.annotations;
/**
* @Transient - mark class or field as transient, to not generate HibernateD persistence metadata for it.
* Use this annotation in cases when field you won't persist will be considered as persistent otherwise.
*/
struct Transient {
immutable bool dummy;
}
/**
* Class level annotations.
*
* HibernateD maps values of some class to DB table. This class is referred as Entity.
*
* Entity contains one or more properties - which are usually mapped to DB table columns.
*/
/**
* Mark class with this annotation if you want to make it persistable.
* @Entity or @Entity() - marks class as entity, using class name as entity name.
*/
struct Entity {
//immutable string name;
immutable bool dummy;
// this(string name) { this.name = name; }
}
/**
* @Embeddable or @Embeddable() - mark class as entity which can only be embedded into other entities, and doesn't have separate columns.
* Columns for each of Embeddable entity properties will be placed into parent entity's table, where this embeddable entity is embedded
*/
struct Embeddable {
immutable bool dummy;
// this(bool enabled) {}
}
/**
* While the `@Embeddable` annotation is applied to a type which can be included in a class in order
* to add its properties as its own, the `@Embedded` annotation is used for the field itself.
*
* If there is only one `@Embeddable` member in a class, then this annotation is implied and
* optional. However, `@Embedded` can include a prefix, which is needed to distinguish multiple
* embedded properties that have the same type.
*
* Example:
* ```
* @Embeddable
* class Address {
* string zip;
* string city;
* string streetAddress;
* }
*
* @Table("customers")
* class Customer {
* @Id @Generated
* long id;
*
* @Embedded("shipping")
* Address shipping; // Adds columns like: shipping_zip, shipping_city
*
* @Embedded("billing")
* Address billing; // Adds columns like: billing_zip, billing_city
* }
* ```
*/
struct Embedded {
string columnPrefix;
}
/**
* Indicates that a class-field represents a composite-key used to uniquely identify rows in a table.
*
* The annotated field must be `@Embeddable` and each of its columns must exist in the table. Each
* field of the class is part of a composite primary key.
*
* For example, consider the database table:
* ```
* CREATE TABLE invoices ( vendor_no VARCHAR(8) NOT NULL, invoice_no VARCHAR(20) NOT NULL, amount_e4 INTEGER);
* ALTER TABLE invoices
* ADD CONSTRAINT invoices_pkey PRIMARY KEY (vendor_no, invoice_no);
* ```
*
* This would be represented in HibernateD by:
* ```
* @Embeddable
* class InvoiceId {
* string vendorNo;
* string invoiceNo;
*
* // To benefit from caching, it is best to define `opEquals`.
* bool opEquals(const InvoiceId o) const @safe {
* return vendorNo == o.vendorNo && invoiceNo == o.invoiceNo;
* }
* }
*
* @Table("invoices")
* class Invoice {
* @EmbeddedId InvoiceId invoiceId;
* int amountE4;
* }
* ```
*/
struct EmbeddedId {
immutable bool dummy;
}
/**
* Use to specify table name for entity.
* @Table("table_name") - specifies table name to store entity in, different from default generated.
* If this annotation not present, table name will be autogenerated as lowercase entity name with conversion of
* CamelCaseEntityName to camel_case_entity_name.
*/
struct Table {
immutable string name;
// this(string name) { this.name = name; }
}
/**
* Property level annotations.
*
* Supported simple types for properties (may be stored in single DB table column):
* byte, short, int, long, ubyte, ushort, uint, ulong, float, double, byte[], ubyte[], string, DateTime, Date, TimeOfDay
*
* Other possible types of properties:
* Embeddable entity class -- implementation in progress
* Entity class Lazy!class -- ManyToOne or OneToOne relation
* Entity class array or LazyCollection!class -- collection for OneToMany or ManyToMany
*
* Supported kinds of property holders:
* field -- just public field
* @property -- D language read/write property
* getField()/setField(x) method pair
*
* Each entity property has a name. It's derived from field, @property or getter/setter name.
* For field and D @property - name of field of property is used as name of entity property, with first letter lowercased.
* For getters/setters, get/set/is prefix is removed from mothod name, and the rest with lowercased first letter is used as property name.
*/
/**
* Mark property as simple persistent property (must be of one of simple types).
*
* - @Column or @Column() - simple column, with name derived from field/property name.
* - @Column("column_name") - simple column with specified name.
* - @Column("column_name", field_length) - simple column with specified name and length (e.g. for varchar).
* - @Column(field_length) - simple column with specified length; column name will be autogenerated
*
* If column name is not specified, lowercased name of property with _ delimited camelCase words is used as column name.
* Field name camelCasePropertyName will be converted to camel_case_property_name column name.
*/
struct Column {
immutable string name;
immutable int length;
// this(string name) { this.name = name; }
// this(string name, int length) { this.name = name; this.length = length; }
// this(int length) { this.length = length; }
}
/**
* @Id or @Id() - mark simple property as primary key of entity.
*/
struct Id {
immutable bool dummy;
}
/**
* @Generated or @Generated() - mark simple property as column as server generated value (e.g. AUTO INCREMENT field)
*/
struct Generated {
immutable bool dummy;
}
/**
* @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); }
*/
struct Generator {
string code;
}
/// standard generator - generates random UUID - for use as @Generator() annotation parameter. Don't forget to import std.uuid
const string UUID_GENERATOR = "std.uuid.randomUUID().toString()";
/**
* @NotNull or @NotNull() - mark entity property as not null (NULLs are not allowed in DB)
* 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)
*/
struct NotNull {
immutable bool dummy;
}
/**
* - @Null or @Null() - mark entity property as nullable (NULLs are allowed in DB)
* - 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)
*/
struct Null {
immutable bool dummy;
}
/**
* - @UniqueKey or @UniqueKey() - mark entity property as unique (UNIQUE INDEX will be created for this column, with autogenerated index name)
* - @UniqueKey(indexName) - mark entity property as unique (UNIQUE INDEX will be created for this column, with specified index name)
* For multiple column unique constraints, use Entity level annotations (TODO).
*/
struct UniqueKey {
immutable string name;
}
/**
* @OneToOne(propertyName) - referenced object uses one-to-one relation, propertyName is referenced entity's property to join with current entity's primary key.
* @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.
*/
struct OneToOne {
immutable string name;
// this(string referencedPropertyName) { this.name = name; }
}
/**
* @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.
*/
struct ManyToOne {
immutable bool dummy;
}
/**
* @JoinColumn(columnName) - specify foreign key column name to join other entity's by its primary key - for @OneToOne relation.
* @JoinColumn or @JoinColumn() - foreign key column name will be autogenerated from referenced entity name, with _fk suffix.
* This annotation is mandatory if property has @OneToOne annotation w/o parameter or @ManyToOne annotation
*/
struct JoinColumn {
immutable string name;
// this(string columnName) { this.name = name; }
}
/**
* @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.
*/
struct OneToMany {
immutable string name;
}
/**
* @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.
* @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.
*/
struct ManyToMany {
immutable string joinTableName;
immutable string joinColumn1;
immutable string joinColumn2;
}
unittest {
@Entity
@Table("user")
class User {
@Id @Generated
@Column("id")
int id;
@Column("name")
string name;
}
}