1 /*
2  * Entity - Entity is an object-relational mapping tool for the D programming language. Referring to the design idea of JPA.
3  *
4  * Copyright (C) 2015-2018  Shanghai Putao Technology Co., Ltd
5  *
6  * Developer: HuntLabs.cn
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.entity.criteria.Root;
13 
14 import hunt.entity;
15 import hunt.logging;
16 import std.traits;
17 
18 interface IRoot {
19 
20 }
21 
22 class Root(T : Object, F: Object = T) : IRoot {
23     private EntityInfo!(T, F) _entityInfo;
24     private CriteriaBuilder _builder;
25     JoinSqlBuild[] _joins;
26     private bool _enableJoin = false;
27 
28     this(CriteriaBuilder builder, T t = null, F owner = null) {
29         _builder = builder;
30         _entityInfo = new EntityInfo!(T, F)(_builder.getManager(), t, owner);
31     }
32 
33     string getEntityClassName() {
34         return _entityInfo.getEntityClassName();
35     }
36 
37     string getTableName() {
38         return _entityInfo.getTableName();
39     }
40 
41     EntityInfo!(T, F) opDispatch(string name)() {
42         if (getEntityClassName() != name)
43             throw new EntityException("Cannot find entityinfo by name : " ~ name);
44         return _entityInfo;
45     }
46 
47     EntityFieldInfo get(string field) {
48         return _entityInfo.getSingleField(field);
49     }
50 
51     T deSerialize(Row[] rows, ref long count, int startIndex, F owner) {
52         return _entityInfo.deSerialize(rows, count, startIndex, owner);
53     }
54 
55     EntityFieldInfo getPrimaryField() {
56         return _entityInfo.getPrimaryField();
57     }
58 
59     EntityInfo!(T, F) getEntityInfo() {
60         return _entityInfo;
61     }
62 
63     JoinSqlBuild[] getJoins() {
64         return _joins;
65     }
66 
67     Join!(T, P) join(P)(EntityFieldInfo info, JoinType joinType = JoinType.INNER) {
68 
69         Join!(T, P) ret = new Join!(T, P)(_builder, info, this, joinType);
70         JoinSqlBuild data = new JoinSqlBuild();
71         data.tableName = ret.getTableName();
72         data.joinWhere = ret.getJoinOnString();
73         data.joinType = joinType;
74         // data.columnNames = [ret.getPrimaryField().getSelectColumn()];
75         data.columnNames = ret.getAllSelectColumn();
76         _joins ~= data;
77 
78         return ret;
79     }
80 
81     string[] getAllSelectColumn() {
82         import std.algorithm;
83 
84         string[] ret;
85         foreach (EntityFieldInfo value; _entityInfo.getFields()) {
86             string name = value.getSelectColumn();
87             version (HUNT_ENTITY_DEBUG_MORE) {
88                 infof("FileldName: %s, JoinPrimaryKey: %s, joinColumn: %s, selectColumn: %s",
89                         value.getFieldName(), value.getJoinPrimaryKey(),
90                         value.getJoinColumn(), name);
91             }
92 
93             if (ret.canFind(name)) {
94                 version (HUNT_ENTITY_DEBUG)
95                     warningf("duplicated column: %s", name);
96                 continue;
97             }
98             
99             if (name != "") {
100                 ret ~= name;
101             }
102         }
103         return ret;
104     }
105 
106     Root!(T, F) autoJoin() {
107         // logDebug("#### join Fields : ",_entityInfo.getFields());
108         foreach (EntityFieldInfo value; _entityInfo.getFields()) {
109             JoinSqlBuild build = value.getJoinSqlData();
110             if(build is null) {
111                 version(HUNT_ENTITY_DEBUG) {
112                     infof("No join for the field [%s] in %s.", value.getFieldName(), T.stringof);
113                 }
114                 continue;
115             }
116 
117             if (_enableJoin || value.isEnableJoin()) {
118                 version(HUNT_ENTITY_DEBUG) {
119                     trace("join sql : ", build.toString());
120                 }
121                 _joins ~= build;
122             }
123         }
124         return this;
125     }
126 
127     void setEnableJoin(bool flg) {
128         _enableJoin = flg;
129     }
130 
131 }