1 /** 2 * HibernateD - 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 hibernated/annotations.d. 8 * 9 * This module contains declarations of HibernateD 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 hibernated.annotations; 16 17 18 19 /** 20 * @Transient - mark class or field as transient, to not generate HibernateD 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 * HibernateD 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 * While the `@Embeddable` annotation is applied to a type which can be included in a class in order 57 * to add its properties as its own, the `@Embedded` annotation is used for the field itself. 58 * 59 * If there is only one `@Embeddable` member in a class, then this annotation is implied and 60 * optional. However, `@Embedded` can include a prefix, which is needed to distinguish multiple 61 * embedded properties that have the same type. 62 * 63 * Example: 64 * ``` 65 * @Embeddable 66 * class Address { 67 * string zip; 68 * string city; 69 * string streetAddress; 70 * } 71 * 72 * @Table("customers") 73 * class Customer { 74 * @Id @Generated 75 * long id; 76 * 77 * @Embedded("shipping") 78 * Address shipping; // Adds columns like: shipping_zip, shipping_city 79 * 80 * @Embedded("billing") 81 * Address billing; // Adds columns like: billing_zip, billing_city 82 * } 83 * ``` 84 */ 85 struct Embedded { 86 string columnPrefix; 87 } 88 89 /** 90 * Use to specify table name for entity. 91 * @Table("table_name") - specifies table name to store entity in, different from default generated. 92 * If this annotation not present, table name will be autogenerated as lowercase entity name with conversion of 93 * CamelCaseEntityName to camel_case_entity_name. 94 */ 95 struct Table { 96 immutable string name; 97 // this(string name) { this.name = name; } 98 } 99 100 /** 101 * Property level annotations. 102 * 103 * Supported simple types for properties (may be stored in single DB table column): 104 * byte, short, int, long, ubyte, ushort, uint, ulong, float, double, byte[], ubyte[], string, DateTime, Date, TimeOfDay 105 * 106 * Other possible types of properties: 107 * Embeddable entity class -- implementation in progress 108 * Entity class Lazy!class -- ManyToOne or OneToOne relation 109 * Entity class array or LazyCollection!class -- collection for OneToMany or ManyToMany 110 * 111 * Supported kinds of property holders: 112 * field -- just public field 113 * @property -- D language read/write property 114 * getField()/setField(x) method pair 115 * 116 * Each entity property has a name. It's derived from field, @property or getter/setter name. 117 * For field and D @property - name of field of property is used as name of entity property, with first letter lowercased. 118 * For getters/setters, get/set/is prefix is removed from mothod name, and the rest with lowercased first letter is used as property name. 119 */ 120 121 /** 122 * Mark property as simple persistent property (must be of one of simple types). 123 * 124 * @Column or @Column() - simple column, with name derived from field/property name. 125 * @Column("column_name") - simple column with specified name. 126 * @Column("column_name", field_length) - simple column with specified name and length (e.g. for varchar). 127 * @Column(field_length) - simple column with specified length; column name will be autogenerated 128 * 129 * If column name is not specified, lowercased name of property with _ delimited camelCase words is used as column name. 130 * Field name camelCasePropertyName will be converted to camel_case_property_name column name. 131 */ 132 struct Column { 133 immutable string name; 134 immutable int length; 135 // this(string name) { this.name = name; } 136 // this(string name, int length) { this.name = name; this.length = length; } 137 // this(int length) { this.length = length; } 138 } 139 140 /** 141 * @Id or @Id() - mark simple property as primary key of entity. 142 */ 143 struct Id { 144 immutable bool dummy; 145 } 146 147 /** 148 * @Generated or @Generated() - mark simple property as column as server generated value (e.g. AUTO INCREMENT field) 149 */ 150 struct Generated { 151 immutable bool dummy; 152 } 153 154 /** 155 * @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); } 156 */ 157 struct Generator { 158 string code; 159 } 160 161 /// standard generator - generates random UUID - for use as @Generator() annotation parameter. Don't forget to import std.uuid 162 const string UUID_GENERATOR = "std.uuid.randomUUID().toString()"; 163 164 /** 165 * @NotNull or @NotNull() - mark entity property as not null (NULLs are not allowed in DB) 166 * 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) 167 */ 168 struct NotNull { 169 immutable bool dummy; 170 } 171 172 /** 173 * @Null or @Null() - mark entity property as nullable (NULLs are allowed in DB) 174 * 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) 175 */ 176 struct Null { 177 immutable bool dummy; 178 } 179 180 /** 181 * @UniqueKey or @UniqueKey() - mark entity property as unique (UNIQUE INDEX will be created for this column, with autogenerated index name) 182 * @UniqueKey(indexName) - mark entity property as unique (UNIQUE INDEX will be created for this column, with specified index name) 183 * For multiple column unique constraints, use Entity level annotations (TODO). 184 */ 185 struct UniqueKey { 186 immutable string name; 187 } 188 189 190 /** 191 * @OneToOne(propertyName) - referenced object uses one-to-one relation, propertyName is referenced entity's property to join with current entity's primary key. 192 * @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. 193 */ 194 struct OneToOne { 195 immutable string name; 196 // this(string referencedPropertyName) { this.name = name; } 197 } 198 199 /** 200 * @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. 201 */ 202 struct ManyToOne { 203 immutable bool dummy; 204 } 205 206 /** 207 * @JoinColumn(columnName) - specify foreign key column name to join other entity's by its primary key - for @OneToOne relation. 208 * @JoinColumn or @JoinColumn() - foreign key column name will be autogenerated from referenced entity name, with _fk suffix. 209 * This annotation is mandatory if property has @OneToOne annotation w/o parameter or @ManyToOne annotation 210 */ 211 struct JoinColumn { 212 immutable string name; 213 // this(string columnName) { this.name = name; } 214 } 215 216 /** 217 * @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. 218 */ 219 struct OneToMany { 220 immutable string name; 221 } 222 223 /** 224 * @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. 225 * @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. 226 */ 227 struct ManyToMany { 228 immutable string joinTableName; 229 immutable string joinColumn1; 230 immutable string joinColumn2; 231 } 232 233 234 unittest { 235 236 @Entity 237 @Table("user") 238 class User { 239 240 @Id @Generated 241 @Column("id") 242 int id; 243 244 @Column("name") 245 string name; 246 } 247 248 }