1 module dorm.annotations;
2 
3 import std.datetime;
4 import std.traits;
5 import std.meta;
6 
7 enum autoCreateTime;
8 enum autoUpdateTime;
9 enum autoIncrement;
10 enum timestamp;
11 enum notNull;
12 
13 alias Id = AliasSeq!(primaryKey, autoIncrement);
14 
15 struct constructValue(alias fn) {}
16 struct validator(alias fn) {}
17 
18 struct maxLength { int maxLength; }
19 
20 alias AllowedDefaultValueTypes = AliasSeq!(
21 	string, ubyte[], byte, short, int, long, ubyte, ushort, uint, ulong, float,
22 	double, bool, Date, DateTime, TimeOfDay, SysTime
23 );
24 enum isAllowedDefaultValueType(T) = staticIndexOf!(T, AllowedDefaultValueTypes) != -1;
25 struct DefaultValue(T) { T value; }
26 auto defaultValue(T)(T value) if (isAllowedDefaultValueType!T)
27 {
28 	return DefaultValue!T(value);
29 }
30 alias PossibleDefaultValueTs = staticMap!(DefaultValue, AllowedDefaultValueTypes);
31 
32 /// Takes the default value from the D default value that's put on the field.
33 ///
34 /// Incompatible with `@constructValue` and `@defaultValue`
35 enum defaultFromInit;
36 enum primaryKey;
37 enum unique;
38 
39 struct Choices { string[] choices; }
40 Choices choices(string[] choices...) { return Choices(choices.dup); }
41 
42 struct columnName { string name; }
43 
44 struct index
45 {
46 	// part of ctor
47 	static struct priority { int priority = 10; }
48 	static struct composite { string name; }
49 
50 	// careful: never duplicate types here, otherwise the automatic ctor doesn't work
51 	priority _priority;
52 	composite _composite;
53 
54 	this(T...)(T args)
55 	{
56 		foreach (ref field; this.tupleof)
57 		{
58 			static foreach (arg; args)
59 			{
60 				static if (is(typeof(field) == typeof(arg)))
61 					field = arg;
62 			}
63 		}
64 	}
65 }
66 
67 enum embedded;
68 enum ignored;
69 
70 /// Checks if the given attribute is part of this dorm.annotations module.
71 template isDormAttribute(alias attr)
72 {
73 	static if (is(typeof(attr) == DefaultValue!T, T))
74 		enum isDormAttribute = true;
75 	else static if (is(typeof(attr)))
76 		enum isDormAttribute = __traits(isSame, __traits(parent, typeof(attr)), dorm.annotations);
77 	else static if (is(attr == constructValue!fn, alias fn))
78 		enum isDormAttribute = true;
79 	else static if (is(attr == validator!fn, alias fn))
80 		enum isDormAttribute = true;
81 	else
82 		enum isDormAttribute = __traits(isSame, __traits(parent, attr), dorm.annotations);
83 }
84 
85 /// Checks if the given attribute affects DORM Fields
86 enum isDormFieldAttribute(alias attr) = isDormAttribute!attr;
87 
88 /// Checks if the given attribute affects DORM Models (classes)
89 enum isDormModelAttribute(alias attr) = isDormAttribute!attr;
90 
91 /// Automatically generated foreign key attribute for one-to-many and many-to-many
92 /// relations. Does not need to be assigned onto any variables.
93 struct ForeignKeyImpl
94 {
95 	string table, column;
96 	ReferentialAction onUpdate = restrict;
97 	ReferentialAction onDelete = restrict;
98 }
99 
100 enum ReferentialAction
101 {
102 	restrict,
103 	cascade,
104 	setNull,
105 	setDefault
106 }
107 
108 enum restrict = ReferentialAction.restrict;
109 enum cascade = ReferentialAction.cascade;
110 enum setNull = ReferentialAction.setNull;
111 enum setDefault = ReferentialAction.setDefault;
112 
113 struct onUpdate
114 {
115 	ReferentialAction type;
116 }
117 
118 struct onDelete
119 {
120 	ReferentialAction type;
121 }