forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSqlFunctionProjection.cs
141 lines (124 loc) · 3.81 KB
/
SqlFunctionProjection.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate.Dialect.Function;
using NHibernate.Engine;
using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Criterion
{
[Serializable]
public class SqlFunctionProjection : SimpleProjection
{
private readonly IProjection[] args;
private readonly ISQLFunction function;
private readonly string functionName;
private readonly IType returnType;
private readonly IProjection returnTypeProjection;
public SqlFunctionProjection(string functionName, IType returnType, params IProjection[] args)
{
this.functionName = functionName;
this.returnType = returnType;
this.args = args;
}
public SqlFunctionProjection(ISQLFunction function, IType returnType, params IProjection[] args)
{
this.function = function;
this.returnType = returnType;
this.args = args;
}
public SqlFunctionProjection(string functionName, IProjection returnTypeProjection, params IProjection[] args)
{
this.functionName = functionName;
this.returnTypeProjection = returnTypeProjection;
this.args = args;
}
public override bool IsAggregate
{
get { return false; }
}
public override bool IsGrouped
{
get
{
foreach (IProjection projection in args)
{
if (projection.IsGrouped)
{
return true;
}
}
return false;
}
}
public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
SqlStringBuilder buf = new SqlStringBuilder();
foreach (IProjection projection in args)
{
if (projection.IsGrouped)
{
buf.Add(projection.ToGroupSqlString(criteria, criteriaQuery)).Add(", ");
}
}
if (buf.Count >= 2)
{
buf.RemoveAt(buf.Count - 1);
}
return buf.ToSqlString();
}
public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery)
{
ISQLFunction sqlFunction = GetFunction(criteriaQuery);
var arguments = new List<object>();
for (int i = 0; i < args.Length; i++)
{
var projectArg = GetProjectionArguments(criteriaQuery, criteria, args[i]);
arguments.AddRange(projectArg);
}
return new SqlString(
sqlFunction.Render(arguments, criteriaQuery.Factory),
" as ",
GetColumnAlias(position));
}
private ISQLFunction GetFunction(ICriteriaQuery criteriaQuery)
{
if (function != null)
{
return function;
}
ISQLFunction dialectFunction = criteriaQuery.Factory.SQLFunctionRegistry.FindSQLFunction(functionName);
if (dialectFunction == null)
{
throw new HibernateException("Current dialect " + criteriaQuery.Factory.Dialect + " doesn't support the function: "
+ functionName);
}
return dialectFunction;
}
private static object[] GetProjectionArguments(ICriteriaQuery criteriaQuery, ICriteria criteria, IProjection projection)
{
return CriterionUtil.GetColumnNamesAsSqlStringParts(projection, criteriaQuery, criteria);
}
public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
var type = GetReturnType(criteria, criteriaQuery);
return type != null ? new[] {type} : Array.Empty<IType>();
}
private IType GetReturnType(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
ISQLFunction sqlFunction = GetFunction(criteriaQuery);
var resultType = returnType ?? returnTypeProjection?.GetTypes(criteria, criteriaQuery).FirstOrDefault();
return sqlFunction.GetReturnType(new[] {resultType}, criteriaQuery.Factory, true);
}
public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
List<TypedValue> types = new List<TypedValue>();
foreach (IProjection projection in args)
{
TypedValue[] argTypes = projection.GetTypedValues(criteria, criteriaQuery);
types.AddRange(argTypes);
}
return types.ToArray();
}
}
}