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 }