Line data Source code
1 : using System;
2 : using System.Linq;
3 : using Cqrs.Configuration;
4 : using Cqrs.Entities;
5 : using Cqrs.DataStores;
6 :
7 : namespace Cqrs.Repositories.Queries
8 : {
9 : public abstract class QueryBuilder<TQueryStrategy, TData> : IQueryBuilder<TQueryStrategy, TData>
10 : where TQueryStrategy : IQueryStrategy
11 : where TData : Entity
12 0 : {
13 : protected IDataStore<TData> DataStore { get; private set; }
14 :
15 : protected IDependencyResolver DependencyResolver { get; private set; }
16 :
17 0 : protected QueryBuilder(IDataStore<TData> dataStore, IDependencyResolver dependencyResolver)
18 : {
19 : DataStore = dataStore;
20 : DependencyResolver = dependencyResolver;
21 : }
22 :
23 : #region Implementation of IQueryBuilder<UserQueryStrategy,User>
24 :
25 0 : public virtual IQueryable<TData> CreateQueryable(ISingleResultQuery<TQueryStrategy, TData> singleResultQuery)
26 : {
27 : IQueryable<TData> queryable = singleResultQuery.QueryStrategy.QueryPredicate == null ? GetEmptyQueryPredicate() : GeneratePredicate(singleResultQuery.QueryStrategy.QueryPredicate);
28 : ApplySorting(singleResultQuery.QueryStrategy, ref queryable);
29 : return queryable;
30 : }
31 :
32 0 : public virtual IQueryable<TData> CreateQueryable(ICollectionResultQuery<TQueryStrategy, TData> collectionResultQuery)
33 : {
34 : IQueryable<TData> queryable = collectionResultQuery.QueryStrategy.QueryPredicate == null ? GetEmptyQueryPredicate() : GeneratePredicate(collectionResultQuery.QueryStrategy.QueryPredicate);
35 : ApplySorting(collectionResultQuery.QueryStrategy, ref queryable);
36 : return queryable;
37 : }
38 :
39 : #endregion
40 :
41 0 : protected virtual IQueryable<TData> GetEmptyQueryPredicate()
42 : {
43 : return DataStore;
44 : }
45 :
46 0 : protected virtual IQueryable<TData> GeneratePredicate(IQueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable = null)
47 : {
48 : var andQueryPredicate = queryPredicate as IAndQueryPredicate;
49 : if (andQueryPredicate != null)
50 : {
51 : IQueryable<TData> innerLeftHandQueryable = GeneratePredicate(andQueryPredicate.LeftQueryPredicate);
52 : return GeneratePredicate(andQueryPredicate.RightQueryPredicate, innerLeftHandQueryable);
53 : }
54 : var orQueryPredicate = queryPredicate as IOrQueryPredicate;
55 : if (orQueryPredicate != null)
56 : {
57 : IQueryable<TData> innerLeftHandQueryable = GeneratePredicate(orQueryPredicate.LeftQueryPredicate);
58 : return GeneratePredicate(orQueryPredicate.RightQueryPredicate, innerLeftHandQueryable);
59 : }
60 : var realQueryPredicate = queryPredicate as QueryPredicate;
61 : if (realQueryPredicate != null)
62 : {
63 : IQueryable<TData> result = GeneratePredicateIsNotLogicallyDeleted(realQueryPredicate, leftHandQueryable);
64 : return result ?? GeneratePredicate(realQueryPredicate, leftHandQueryable);
65 : }
66 : throw new InvalidOperationException(string.Format("The query predicate '{0}' is unable to be processed.", queryPredicate == null ? typeof(void) : queryPredicate.GetType()));
67 : }
68 :
69 0 : protected virtual IQueryable<TData> GeneratePredicateIsNotLogicallyDeleted(QueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable = null)
70 : {
71 : var queryStrategy = GetNullQueryStrategy() as QueryStrategy;
72 :
73 : if (queryStrategy == null)
74 : return null;
75 :
76 : if (queryPredicate.Name != GetFunctionName(queryStrategy.IsNotLogicallyDeleted))
77 : return null;
78 :
79 : return (leftHandQueryable ?? GetEmptyQueryPredicate()).Where
80 : (
81 : entity => !entity.IsLogicallyDeleted
82 : );
83 : }
84 :
85 0 : protected virtual IQueryable<TData> GeneratePredicateWithPermissionScopeAny<TAuthenticationToken>(QueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable)
86 : {
87 : var queryStrategy = GetNullQueryStrategy() as QueryStrategy;
88 :
89 : if (queryStrategy == null)
90 : return null;
91 :
92 : if (queryPredicate.Name != GetFunctionNameOfType<TAuthenticationToken>(queryStrategy.WithPermissionScopeAny))
93 : return null;
94 :
95 : return OnGeneratePredicateWithPermissionScopeAny<TAuthenticationToken>(queryPredicate, leftHandQueryable);
96 : }
97 :
98 0 : protected virtual IQueryable<TData> OnGeneratePredicateWithPermissionScopeAny<TAuthenticationToken>(QueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable)
99 : {
100 : return (leftHandQueryable ?? GetEmptyQueryPredicate());
101 : }
102 :
103 0 : protected virtual IQueryable<TData> GeneratePredicateWithPermissionScopeUser<TAuthenticationToken>(QueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable)
104 : {
105 : var queryStrategy = GetNullQueryStrategy() as QueryStrategy;
106 :
107 : if (queryStrategy == null)
108 : return null;
109 :
110 : if (queryPredicate.Name != GetFunctionNameOfType<TAuthenticationToken>(queryStrategy.WithPermissionScopeUser))
111 : return null;
112 :
113 : return OnGeneratePredicateWithPermissionScopeUser<TAuthenticationToken>(queryPredicate, leftHandQueryable);
114 : }
115 :
116 0 : protected virtual IQueryable<TData> OnGeneratePredicateWithPermissionScopeUser<TAuthenticationToken>(QueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable)
117 : {
118 : return (leftHandQueryable ?? GetEmptyQueryPredicate());
119 : }
120 :
121 0 : protected virtual IQueryable<TData> GeneratePredicateWithPermissionScopeCompany<TAuthenticationToken>(QueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable)
122 : {
123 : var queryStrategy = GetNullQueryStrategy() as QueryStrategy;
124 :
125 : if (queryStrategy == null)
126 : return null;
127 :
128 : if (queryPredicate.Name != GetFunctionNameOfType<TAuthenticationToken>(queryStrategy.WithPermissionScopeCompany))
129 : return null;
130 :
131 : return OnGeneratePredicateWithPermissionScopeCompany<TAuthenticationToken>(queryPredicate, leftHandQueryable);
132 : }
133 :
134 0 : protected virtual IQueryable<TData> OnGeneratePredicateWithPermissionScopeCompany<TAuthenticationToken>(QueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable)
135 : {
136 : return (leftHandQueryable ?? GetEmptyQueryPredicate());
137 : }
138 :
139 0 : protected virtual IQueryable<TData> GeneratePredicateWithPermissionScopeCompanyAndUser<TAuthenticationToken>(QueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable)
140 : {
141 : var queryStrategy = GetNullQueryStrategy() as QueryStrategy;
142 :
143 : if (queryStrategy == null)
144 : return null;
145 :
146 : if (queryPredicate.Name != GetFunctionNameOfType<TAuthenticationToken>(queryStrategy.WithPermissionScopeCompanyAndUser))
147 : return null;
148 :
149 : return OnGeneratePredicateWithPermissionScopeCompanyAndUser<TAuthenticationToken>(queryPredicate, leftHandQueryable);
150 : }
151 :
152 0 : protected virtual IQueryable<TData> OnGeneratePredicateWithPermissionScopeCompanyAndUser<TAuthenticationToken>(QueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable)
153 : {
154 : return (leftHandQueryable ?? GetEmptyQueryPredicate());
155 : }
156 :
157 0 : protected abstract IQueryable<TData> GeneratePredicate(QueryPredicate queryPredicate, IQueryable<TData> leftHandQueryable = null);
158 :
159 0 : protected virtual string GetFunctionNameOfType<TParameter1>(Func<TParameter1, IQueryPredicate> expression)
160 : {
161 : return expression.Method.Name;
162 : }
163 :
164 0 : protected virtual string GetFunctionName<T>(Func<T> expression)
165 : {
166 : return expression.Method.Name;
167 : }
168 :
169 0 : protected virtual string GetFunctionName<TParameter1>(Func<TParameter1, TQueryStrategy> expression)
170 : {
171 : return expression.Method.Name;
172 : }
173 :
174 0 : protected virtual string GetFunctionName<TParameter1, TParameter2>(Func<TParameter1, TParameter2, TQueryStrategy> expression)
175 : {
176 : return expression.Method.Name;
177 : }
178 :
179 0 : protected virtual string GetFunctionName<TParameter1, TParameter2, TParameter3>(Func<TParameter1, TParameter2, TParameter3, TQueryStrategy> expression)
180 : {
181 : return expression.Method.Name;
182 : }
183 :
184 0 : protected virtual string GetFunctionName<TParameter1, TParameter2, TParameter3, TParameter4>(Func<TParameter1, TParameter2, TParameter3, TParameter4, TQueryStrategy> expression)
185 : {
186 : return expression.Method.Name;
187 : }
188 :
189 0 : protected virtual string GetFunctionName<TParameter1, TParameter2, TParameter3, TParameter4, TParameter5>(Func<TParameter1, TParameter2, TParameter3, TParameter4, TParameter5, TQueryStrategy> expression)
190 : {
191 : return expression.Method.Name;
192 : }
193 :
194 0 : protected virtual TQueryStrategy GetNullQueryStrategy()
195 : {
196 : return DependencyResolver.Resolve<TQueryStrategy>();
197 : }
198 :
199 0 : protected virtual void ApplySorting(TQueryStrategy queryStrategy, ref IQueryable<TData> queryable)
200 : {
201 : }
202 : }
203 : }
|