7
7
using System . Reflection ;
8
8
using System . Text ;
9
9
using System . Linq . Expressions ;
10
- using System . Runtime . CompilerServices ;
11
10
using System . Text . RegularExpressions ;
12
- using ServiceStack . OrmLite . Converters ;
13
- using ServiceStack . OrmLite . Dapper ;
14
11
using ServiceStack . Text ;
15
12
16
13
namespace ServiceStack . OrmLite
@@ -20,9 +17,6 @@ public abstract partial class SqlExpression<T> : ISqlExpression, IHasUntypedSqlE
20
17
public const string TrueLiteral = "(1=1)" ;
21
18
public const string FalseLiteral = "(1=0)" ;
22
19
23
- protected bool visitedExpressionIsTableColumn = false ;
24
- protected bool skipParameterizationForThisExpression = false ;
25
-
26
20
private Expression < Func < T , bool > > underlyingExpression ;
27
21
private List < string > orderByProperties = new List < string > ( ) ;
28
22
private string selectExpression = string . Empty ;
@@ -37,20 +31,25 @@ public abstract partial class SqlExpression<T> : ISqlExpression, IHasUntypedSqlE
37
31
public List < string > InsertFields { get ; set ; }
38
32
39
33
private string sep = string . Empty ;
40
- protected bool useFieldName = false ;
41
- protected bool selectDistinct = false ;
42
- protected bool CustomSelect { get ; set ; }
43
34
protected ModelDefinition modelDef ;
44
- public bool PrefixFieldWithTableName { get ; set ; }
45
35
public string TableAlias { get ; set ; }
46
- public bool WhereStatementWithoutWhereString { get ; set ; }
47
36
public IOrmLiteDialectProvider DialectProvider { get ; set ; }
48
37
public List < IDbDataParameter > Params { get ; set ; }
49
38
public Func < string , string > SqlFilter { get ; set ; }
50
39
public static Action < SqlExpression < T > > SelectFilter { get ; set ; }
51
40
public int ? Rows { get ; set ; }
52
41
public int ? Offset { get ; set ; }
42
+ public bool PrefixFieldWithTableName { get ; set ; }
53
43
public bool UseSelectPropertiesAsAliases { get ; set ; }
44
+ public bool WhereStatementWithoutWhereString { get ; set ; }
45
+
46
+ protected bool CustomSelect { get ; set ; }
47
+ protected bool useFieldName = false ;
48
+ protected bool selectDistinct = false ;
49
+ protected bool visitedExpressionIsTableColumn = false ;
50
+ protected bool skipParameterizationForThisExpression = false ;
51
+ private bool hasEnsureConditions = false ;
52
+ private bool inSqlMethodCall = false ;
54
53
55
54
protected string Sep => sep ;
56
55
@@ -81,36 +80,114 @@ public SqlExpression<T> Clone()
81
80
82
81
protected virtual SqlExpression < T > CopyTo ( SqlExpression < T > to )
83
82
{
84
- to . visitedExpressionIsTableColumn = visitedExpressionIsTableColumn ;
85
- to . skipParameterizationForThisExpression = skipParameterizationForThisExpression ;
86
- to . underlyingExpression = underlyingExpression ;
87
- to . orderByProperties = orderByProperties ;
83
+ to . modelDef = modelDef ;
84
+ to . tableDefs = tableDefs ;
85
+
88
86
to . selectExpression = selectExpression ;
87
+ to . OnlyFields = OnlyFields != null ? new HashSet < string > ( OnlyFields , StringComparer . OrdinalIgnoreCase ) : null ;
88
+
89
+ to . UpdateFields = UpdateFields ;
90
+ to . InsertFields = InsertFields ;
91
+
92
+ to . TableAlias = TableAlias ;
89
93
to . fromExpression = fromExpression ;
90
94
to . whereExpression = whereExpression ;
91
95
to . groupBy = groupBy ;
92
96
to . havingExpression = havingExpression ;
93
97
to . orderBy = orderBy ;
94
- to . OnlyFields = OnlyFields != null ? new HashSet < string > ( OnlyFields , StringComparer . OrdinalIgnoreCase ) : null ;
95
- to . UpdateFields = UpdateFields ;
96
- to . InsertFields = InsertFields ;
97
- to . useFieldName = useFieldName ;
98
- to . selectDistinct = selectDistinct ;
98
+ to . orderByProperties = orderByProperties ;
99
+
100
+ to . Offset = Offset ;
101
+ to . Rows = Rows ;
102
+
99
103
to . CustomSelect = CustomSelect ;
100
- to . modelDef = modelDef ;
101
104
to . PrefixFieldWithTableName = PrefixFieldWithTableName ;
102
- to . TableAlias = TableAlias ;
105
+ to . useFieldName = useFieldName ;
106
+ to . selectDistinct = selectDistinct ;
103
107
to . WhereStatementWithoutWhereString = WhereStatementWithoutWhereString ;
104
- to . Params = new List < IDbDataParameter > ( Params ) ;
105
- to . SqlFilter = SqlFilter ;
106
- to . Offset = Offset ;
107
- to . Rows = Rows ;
108
- to . tableDefs = tableDefs ;
108
+ to . visitedExpressionIsTableColumn = visitedExpressionIsTableColumn ;
109
+ to . skipParameterizationForThisExpression = skipParameterizationForThisExpression ;
109
110
to . UseSelectPropertiesAsAliases = UseSelectPropertiesAsAliases ;
110
111
to . hasEnsureConditions = hasEnsureConditions ;
112
+
113
+ to . Params = new List < IDbDataParameter > ( Params ) ;
114
+
115
+ to . underlyingExpression = underlyingExpression ;
116
+ to . SqlFilter = SqlFilter ;
117
+
111
118
return to ;
112
119
}
113
120
121
+ /// <summary>
122
+ /// Generate a unique SHA1 hash of expression with param values for caching
123
+ /// </summary>
124
+ public string ComputeHash ( )
125
+ {
126
+ var sb = StringBuilderCache . Allocate ( ) ;
127
+
128
+ if ( ! string . IsNullOrEmpty ( SelectExpression ) )
129
+ sb . AppendLine ( SelectExpression ) ;
130
+ if ( ! OnlyFields . IsEmpty ( ) )
131
+ sb . AppendLine ( OnlyFields . Join ( "," ) ) ;
132
+
133
+ if ( ! UpdateFields . IsEmpty ( ) )
134
+ sb . AppendLine ( UpdateFields . Join ( "," ) ) ;
135
+ if ( ! InsertFields . IsEmpty ( ) )
136
+ sb . AppendLine ( InsertFields . Join ( "," ) ) ;
137
+
138
+ if ( ! string . IsNullOrEmpty ( TableAlias ) )
139
+ sb . AppendLine ( TableAlias ) ;
140
+ if ( ! string . IsNullOrEmpty ( fromExpression ) )
141
+ sb . AppendLine ( fromExpression ) ;
142
+
143
+ if ( ! string . IsNullOrEmpty ( whereExpression ) )
144
+ sb . AppendLine ( whereExpression ) ;
145
+
146
+ if ( ! string . IsNullOrEmpty ( groupBy ) )
147
+ sb . AppendLine ( groupBy ) ;
148
+
149
+ if ( ! string . IsNullOrEmpty ( havingExpression ) )
150
+ sb . AppendLine ( havingExpression ) ;
151
+
152
+ if ( ! string . IsNullOrEmpty ( orderBy ) )
153
+ sb . AppendLine ( orderBy ) ;
154
+ if ( ! orderByProperties . IsEmpty ( ) )
155
+ sb . AppendLine ( orderByProperties . Join ( "," ) ) ;
156
+
157
+ if ( Offset != null || Rows != null )
158
+ sb . Append ( Offset ?? 0 ) . Append ( ',' ) . Append ( Rows ?? 0 ) . AppendLine ( ) ;
159
+
160
+ var flags = 0 ;
161
+ sb . Append ( "FLAGS=" ) ;
162
+ sb . Append ( CustomSelect ? "1" : "0" ) ;
163
+ sb . Append ( PrefixFieldWithTableName ? "1" : "0" ) ;
164
+ sb . Append ( useFieldName ? "1" : "0" ) ;
165
+ sb . Append ( selectDistinct ? "1" : "0" ) ;
166
+ sb . Append ( WhereStatementWithoutWhereString ? "1" : "0" ) ;
167
+ sb . Append ( visitedExpressionIsTableColumn ? "1" : "0" ) ;
168
+ sb . Append ( skipParameterizationForThisExpression ? "1" : "0" ) ;
169
+ sb . Append ( UseSelectPropertiesAsAliases ? "1" : "0" ) ;
170
+ sb . Append ( hasEnsureConditions ? "1" : "0" ) ;
171
+
172
+ if ( Params . Count > 0 )
173
+ {
174
+ sb . AppendLine ( "PARAMS=" ) ;
175
+ for ( var i = 0 ; i < Params . Count ; i ++ )
176
+ {
177
+ sb . AppendLine ( Params [ i ] . Value . ConvertTo < string > ( ) ) ;
178
+ }
179
+ sb . AppendLine ( ) ;
180
+ }
181
+
182
+ var uniqueExpr = StringBuilderCache . ReturnAndFree ( sb ) ;
183
+ // fastest up to 500 chars https://wintermute79.wordpress.com/2014/10/10/c-sha-1-benchmark/
184
+ using var sha1 = new System . Security . Cryptography . SHA1Managed ( ) ;
185
+ var hash = sha1 . ComputeHash ( Encoding . ASCII . GetBytes ( uniqueExpr ) ) ;
186
+ var hexFormat = hash . ToHex ( ) ;
187
+
188
+ return hexFormat ;
189
+ }
190
+
114
191
/// <summary>
115
192
/// Clear select expression. All properties will be selected.
116
193
/// </summary>
@@ -621,7 +698,6 @@ protected SqlExpression<T> AppendToEnsure(Expression predicate)
621
698
return Ensure ( newExpr ) ;
622
699
}
623
700
624
- private bool hasEnsureConditions = false ;
625
701
/// <summary>
626
702
/// Add a WHERE Condition to always be applied, irrespective of other WHERE conditions
627
703
/// </summary>
@@ -2312,7 +2388,6 @@ protected virtual bool IsColumnAccess(MethodCallExpression m)
2312
2388
&& IsJoinedTable ( exp . Expression . Type ) ;
2313
2389
}
2314
2390
2315
- private bool inSqlMethodCall = false ;
2316
2391
2317
2392
protected virtual object VisitMethodCall ( MethodCallExpression m )
2318
2393
{
0 commit comments