1 module hunt.entity.EntityInfoMaker;
2 
3 import hunt.entity.eql.Common;
4 
5 import hunt.entity;
6 import hunt.entity.EntityDeserializer;
7 import hunt.entity.EntityMetaInfo;
8 import hunt.entity.DefaultEntityManagerFactory;
9 import hunt.entity.dialect;
10 
11 import hunt.logging;
12 
13 import std.conv;
14 import std.string;
15 import std.traits;
16 import std.variant;
17 
18 
19 string makeInitEntityData(T,F)() {
20     import std.conv;
21 
22     string str = `
23     private void initEntityData() {
24     `;
25 
26     static if (hasUDA!(T, Factory)) {
27         str ~= `
28         _factoryName = `~ getUDAs!(getSymbolsByUDA!(T,Factory)[0], Factory)[0].name~`;`;
29     }
30 
31     //
32     static foreach (string memberName; FieldNameTuple!T) {{
33         alias currentMember = __traits(getMember, T, memberName);
34 
35         static if (__traits(getProtection, currentMember) != "public") {
36             enum isEntityMember = false;
37         } else static if(hasUDA!(currentMember, Transient)) {
38             enum isEntityMember = false;
39         } else {
40             enum isEntityMember = true;
41         }
42 
43         static if (isEntityMember) {
44             alias memType = typeof(currentMember);
45             //columnName nullable
46             string nullable;
47             string columnName;
48             string mappedBy;
49             static if(hasUDA!(currentMember, ManyToMany))
50             {
51                 mappedBy = "\""~getUDAs!(currentMember, ManyToMany)[0].mappedBy~"\"";
52             }
53 
54             static if (hasUDA!(currentMember, Column)) {
55                 columnName = "\""~getUDAs!(currentMember, Column)[0].name~"\"";
56                 nullable = getUDAs!(currentMember, Column)[0].nullable.to!string;
57             } else static if (hasUDA!(currentMember, JoinColumn)) {
58                 columnName = "\""~getUDAs!(currentMember, JoinColumn)[0].name~"\"";
59                 nullable = getUDAs!(currentMember, JoinColumn)[0].nullable.to!string;
60             } 
61             else {
62                 columnName = "\""~currentMember.stringof~"\"";
63             }
64             //value 
65             string value = "_data."~memberName;
66             
67             // Use the field/member name as the key
68             string fieldName = "_fields["~memberName.stringof~"]";
69             static if (is(F == memType) ) {
70                 str ~= `
71             `~fieldName~` = new EntityFieldOwner(`~memberName.stringof~`, toColumnName(`~columnName~`), _tableName);`;
72                     
73             }
74             else static if( memType.stringof.replace("[]","") == F.stringof && hasUDA!(currentMember, ManyToMany))
75             {
76                 string owner = (getUDAs!(currentMember, ManyToMany)[0]).mappedBy == "" ? "_data" : "_owner";
77 
78                 static if (hasUDA!(currentMember, JoinTable))
79                         {
80                 str ~= `
81                 `~fieldName~` = new EntityFieldManyToManyOwner!(`
82                                 ~ memType.stringof.replace("[]","")
83                                 ~ `,F,`~mappedBy~`)(_manager, `~memberName.stringof~`, _primaryKey, _tableName, `
84                                 ~ (getUDAs!(currentMember, ManyToMany)[0]).stringof~`, `~owner~`,true,`
85                                 ~ (getUDAs!(currentMember, JoinTable)[0]).stringof~`,`
86                                 ~ (getUDAs!(currentMember, JoinColumn)[0]).stringof~`,`
87                                 ~ (getUDAs!(currentMember, InverseJoinColumn)[0]).stringof~ `);`;
88                         }
89                         else
90                         {
91                 str ~= `
92                 `~fieldName~` = new EntityFieldManyToManyOwner!(`~memType.stringof.replace("[]","")~`, F,`~mappedBy~`)(_manager, `~memberName.stringof~`, _primaryKey, _tableName, `
93                                                 ~(getUDAs!(currentMember, ManyToMany)[0]).stringof~`, `~owner~`,false);`;
94                         }
95             }
96             else static if (hasUDA!(currentMember, OneToOne)) {
97                 static if(is(memType == T)) {
98                     enum string owner = (getUDAs!(currentMember, OneToOne)[0]).mappedBy == "" ? "_owner" : "_data";
99                 } else {
100                     enum string owner = "_data";
101                 }
102     str ~= `
103     `~fieldName~` = new EntityFieldOneToOne!(`~memType.stringof~`, T)(_manager, `~memberName.stringof ~ 
104                 `, _primaryKey, toColumnName(`~columnName~`), _tableName, `~value~`, `
105                                 ~ (getUDAs!(currentMember, OneToOne)[0]).stringof ~ `, `~owner ~ `);`;
106             }
107             else static if (hasUDA!(currentMember, OneToMany)) {
108                 static if (is(T==F)) {
109     str ~= `
110     `~fieldName~` = new EntityFieldOneToMany!(`~memType.stringof.replace("[]","")~`, F)(_manager, `~memberName.stringof~`, _primaryKey, _tableName, `
111                                     ~(getUDAs!(currentMember, OneToMany)[0]).stringof~`, _owner);`;
112                 }
113                 else {
114     str ~= `
115     `~fieldName~` = new EntityFieldOneToMany!(`~memType.stringof.replace("[]","")~`, T)(_manager, `~memberName.stringof~`, _primaryKey, _tableName, `
116                                     ~(getUDAs!(currentMember, OneToMany)[0]).stringof~`, _data);`;
117                 }
118             }
119             else static if (hasUDA!(currentMember, ManyToOne)) {
120     str ~= `
121     `~fieldName~` = new EntityFieldManyToOne!(`~memType.stringof~`)(_manager, `~memberName.stringof~`, toColumnName(`~columnName~`), _tableName, `~value~`, `
122                                 ~(getUDAs!(currentMember, ManyToOne)[0]).stringof~`);`;
123             }
124             else static if (hasUDA!(currentMember, ManyToMany)) {
125                 //TODO
126                 string owner = (getUDAs!(currentMember, ManyToMany)[0]).mappedBy == "" ? "_owner" : "_data";
127 
128                 static if (hasUDA!(currentMember, JoinTable))
129                 {
130         str ~= `
131         `~fieldName~` = new EntityFieldManyToMany!(`~memType.stringof.replace("[]","")~`,T,`~mappedBy~`)(_manager, `~memberName.stringof~`, _primaryKey, _tableName, `
132                                         ~(getUDAs!(currentMember, ManyToMany)[0]).stringof~`, `~owner~`,true,`
133                                         ~(getUDAs!(currentMember, JoinTable)[0]).stringof~`,`
134                                         ~(getUDAs!(currentMember, JoinColumn)[0]).stringof~`,`
135                                         ~(getUDAs!(currentMember, InverseJoinColumn)[0]).stringof~ `);`;
136                 }
137                 else
138                 {
139         str ~= `
140         `~fieldName~` = new EntityFieldManyToMany!(`~memType.stringof.replace("[]","")~`, T,`~mappedBy~`)(_manager, `~memberName.stringof~`, _primaryKey, _tableName, `
141                                         ~(getUDAs!(currentMember, ManyToMany)[0]).stringof~`, `~owner~`,false);`;
142                 }
143             }
144             else {
145                 // string fieldType =  "new "~getDlangDataTypeStr!memType~"()";
146     str ~= `
147     `~fieldName~` = new EntityFieldNormal!(`~memType.stringof~`)(_manager, `~memberName.stringof~`, `~columnName~`, _tableName, `~value~`);`;
148             }
149 
150             //nullable
151             if (nullable != "" && nullable != "true")
152     str ~= `
153     `~fieldName~`.setNullable(`~nullable~`);`;
154             //primary key
155             static if (hasUDA!(currentMember, PrimaryKey) || hasUDA!(currentMember, Id)) {
156     str ~= `
157     _primaryKey = `~memberName.stringof~`;
158     `~fieldName~`.setPrimary(true);`;
159             }
160             //autoincrease key
161             static if (hasUDA!(currentMember, AutoIncrement) || hasUDA!(currentMember, Auto)) {
162     str ~= `
163     _autoIncrementKey = `~memberName.stringof~`;
164     `~fieldName~`.setAuto(true);
165     `~fieldName~`.setNullable(false);`;
166             }
167         }
168     }}
169 
170     str ~=`
171         if (_fields.length == 0) {
172             throw new EntityException("Entity class member cannot be empty : `~ T.stringof~`");
173         }
174     }`;
175     return str;
176 }