1
1
using System ;
2
2
using System . Collections ;
3
+ using System . Collections . Concurrent ;
4
+ using System . Collections . Generic ;
5
+ using System . Threading ;
6
+ using System . Threading . Tasks ;
3
7
using NHibernate . Dialect ;
4
8
using NUnit . Framework ;
5
9
@@ -21,6 +25,18 @@ static HQLFunctions()
21
25
{ "locate" , new [ ] { typeof ( SQLiteDialect ) } } ,
22
26
{ "bit_length" , new [ ] { typeof ( SQLiteDialect ) } } ,
23
27
{ "extract" , new [ ] { typeof ( SQLiteDialect ) } } ,
28
+ {
29
+ "bxor" ,
30
+ new [ ]
31
+ {
32
+ // Could be supported like Oracle, with a template
33
+ typeof ( SQLiteDialect ) ,
34
+ // Could be supported by overriding registration with # instead of ^
35
+ typeof ( PostgreSQLDialect ) ,
36
+ typeof ( PostgreSQL81Dialect ) ,
37
+ typeof ( PostgreSQL82Dialect )
38
+ }
39
+ } ,
24
40
{ "nullif" , new [ ] { typeof ( Oracle8iDialect ) } }
25
41
} ;
26
42
}
@@ -1014,7 +1030,202 @@ public void ParameterLikeArgument()
1014
1030
Assert . AreEqual ( 1 , l . Count ) ;
1015
1031
}
1016
1032
}
1033
+
1034
+ [ Test ]
1035
+ public void BitwiseAnd ( )
1036
+ {
1037
+ IgnoreIfNotSupported ( "band" ) ;
1038
+ CreateMaterialResources ( ) ;
1039
+
1040
+ using ( var s = OpenSession ( ) )
1041
+ using ( var tx = s . BeginTransaction ( ) )
1042
+ {
1043
+ var query = s . CreateQuery ( "from MaterialResource m where (m.State & 1) > 0" ) ;
1044
+ var result = query . List ( ) ;
1045
+ Assert . That ( result , Has . Count . EqualTo ( 1 ) , "& 1" ) ;
1046
+
1047
+ query = s . CreateQuery ( "from MaterialResource m where (m.State & 2) > 0" ) ;
1048
+ result = query . List ( ) ;
1049
+ Assert . That ( result , Has . Count . EqualTo ( 1 ) , "& 2" ) ;
1050
+
1051
+ query = s . CreateQuery ( "from MaterialResource m where (m.State & 3) > 0" ) ;
1052
+ result = query . List ( ) ;
1053
+ Assert . That ( result , Has . Count . EqualTo ( 2 ) , "& 3" ) ;
1054
+
1055
+ tx . Commit ( ) ;
1056
+ }
1057
+ DeleteMaterialResources ( ) ;
1058
+ }
1059
+
1060
+ [ Test ]
1061
+ public void BitwiseOr ( )
1062
+ {
1063
+ IgnoreIfNotSupported ( "bor" ) ;
1064
+ CreateMaterialResources ( ) ;
1065
+
1066
+ using ( var s = OpenSession ( ) )
1067
+ using ( var tx = s . BeginTransaction ( ) )
1068
+ {
1069
+ var query = s . CreateQuery ( "from MaterialResource m where (m.State | 1) > 0" ) ;
1070
+ var result = query . List ( ) ;
1071
+ Assert . That ( result , Has . Count . EqualTo ( 3 ) , "| 1) > 0" ) ;
1072
+
1073
+ query = s . CreateQuery ( "from MaterialResource m where (m.State | 1) > 1" ) ;
1074
+ result = query . List ( ) ;
1075
+ Assert . That ( result , Has . Count . EqualTo ( 1 ) , "| 1) > 1" ) ;
1076
+
1077
+ query = s . CreateQuery ( "from MaterialResource m where (m.State | 0) > 0" ) ;
1078
+ result = query . List ( ) ;
1079
+ Assert . That ( result , Has . Count . EqualTo ( 2 ) , "| 0) > 0" ) ;
1080
+
1081
+ tx . Commit ( ) ;
1082
+ }
1083
+ DeleteMaterialResources ( ) ;
1084
+ }
1085
+
1086
+ [ Test ]
1087
+ public void BitwiseXor ( )
1088
+ {
1089
+ IgnoreIfNotSupported ( "bxor" ) ;
1090
+ CreateMaterialResources ( ) ;
1091
+
1092
+ using ( var s = OpenSession ( ) )
1093
+ using ( var tx = s . BeginTransaction ( ) )
1094
+ {
1095
+ var query = s . CreateQuery ( "from MaterialResource m where (m.State ^ 1) > 0" ) ;
1096
+ var result = query . List ( ) ;
1097
+ Assert . That ( result , Has . Count . EqualTo ( 2 ) , "^ 1" ) ;
1098
+
1099
+ query = s . CreateQuery ( "from MaterialResource m where (m.State ^ 2) > 0" ) ;
1100
+ result = query . List ( ) ;
1101
+ Assert . That ( result , Has . Count . EqualTo ( 2 ) , "^ 2" ) ;
1102
+
1103
+ query = s . CreateQuery ( "from MaterialResource m where (m.State ^ 3) > 0" ) ;
1104
+ result = query . List ( ) ;
1105
+ Assert . That ( result , Has . Count . EqualTo ( 3 ) , "^ 3" ) ;
1106
+
1107
+ tx . Commit ( ) ;
1108
+ }
1109
+ DeleteMaterialResources ( ) ;
1110
+ }
1111
+
1112
+ [ Test ]
1113
+ public void BitwiseNot ( )
1114
+ {
1115
+ IgnoreIfNotSupported ( "bnot" ) ;
1116
+ IgnoreIfNotSupported ( "band" ) ;
1117
+ CreateMaterialResources ( ) ;
1118
+
1119
+ using ( var s = OpenSession ( ) )
1120
+ using ( var tx = s . BeginTransaction ( ) )
1121
+ {
1122
+ // ! takes not precedence over & at least with some dialects (maybe all).
1123
+ var query = s . CreateQuery ( "from MaterialResource m where ((!m.State) & 3) = 3" ) ;
1124
+ var result = query . List ( ) ;
1125
+ Assert . That ( result , Has . Count . EqualTo ( 1 ) , "((!m.State) & 3) = 3" ) ;
1126
+
1127
+ query = s . CreateQuery ( "from MaterialResource m where ((!m.State) & 3) = 2" ) ;
1128
+ result = query . List ( ) ;
1129
+ Assert . That ( result , Has . Count . EqualTo ( 1 ) , "((!m.State) & 3) = 2" ) ;
1130
+
1131
+ query = s . CreateQuery ( "from MaterialResource m where ((!m.State) & 3) = 1" ) ;
1132
+ result = query . List ( ) ;
1133
+ Assert . That ( result , Has . Count . EqualTo ( 1 ) , "((!m.State) & 3) = 1" ) ;
1134
+
1135
+ tx . Commit ( ) ;
1136
+ }
1137
+ DeleteMaterialResources ( ) ;
1138
+ }
1139
+
1140
+ // #1670
1141
+ [ Test ]
1142
+ public void BitwiseIsThreadsafe ( )
1143
+ {
1144
+ IgnoreIfNotSupported ( "band" ) ;
1145
+ IgnoreIfNotSupported ( "bor" ) ;
1146
+ IgnoreIfNotSupported ( "bxor" ) ;
1147
+ IgnoreIfNotSupported ( "bnot" ) ;
1148
+ var queries = new List < Tuple < string , int > >
1149
+ {
1150
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where (m.State & 1) > 0" , 1 ) ,
1151
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where (m.State & 2) > 0" , 1 ) ,
1152
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where (m.State & 3) > 0" , 2 ) ,
1153
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where (m.State | 1) > 0" , 3 ) ,
1154
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where (m.State | 1) > 1" , 1 ) ,
1155
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where (m.State | 0) > 0" , 2 ) ,
1156
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where (m.State ^ 1) > 0" , 2 ) ,
1157
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where (m.State ^ 2) > 0" , 2 ) ,
1158
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where (m.State ^ 3) > 0" , 3 ) ,
1159
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where ((!m.State) & 3) = 3" , 1 ) ,
1160
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where ((!m.State) & 3) = 2" , 1 ) ,
1161
+ new Tuple < string , int > ( "select count(*) from MaterialResource m where ((!m.State) & 3) = 1" , 1 )
1162
+ } ;
1163
+ // Do not use a ManualResetEventSlim, it does not support async and exhausts the task thread pool in the
1164
+ // async counterparts of this test. SemaphoreSlim has the async support and release the thread when waiting.
1165
+ var semaphore = new SemaphoreSlim ( 0 ) ;
1166
+ var failures = new ConcurrentBag < Exception > ( ) ;
1167
+
1168
+ CreateMaterialResources ( ) ;
1169
+
1170
+ Parallel . For (
1171
+ 0 , queries . Count + 1 ,
1172
+ i =>
1173
+ {
1174
+ if ( i >= queries . Count )
1175
+ {
1176
+ // Give some time to threads for reaching the wait, having all of them ready to do the
1177
+ // critical part of their job concurrently.
1178
+ Thread . Sleep ( 100 ) ;
1179
+ semaphore . Release ( queries . Count ) ;
1180
+ return ;
1181
+ }
1182
+
1183
+ try
1184
+ {
1185
+ var query = queries [ i ] ;
1186
+ using ( var s = OpenSession ( ) )
1187
+ using ( var tx = s . BeginTransaction ( ) )
1188
+ {
1189
+ semaphore . Wait ( ) ;
1190
+ var q = s . CreateQuery ( query . Item1 ) ;
1191
+ var result = q . UniqueResult < long > ( ) ;
1192
+ Assert . That ( result , Is . EqualTo ( query . Item2 ) , query . Item1 ) ;
1193
+ tx . Commit ( ) ;
1194
+ }
1195
+ }
1196
+ catch ( Exception e )
1197
+ {
1198
+ failures . Add ( e ) ;
1199
+ }
1200
+ } ) ;
1201
+
1202
+ Assert . That ( failures , Is . Empty , $ "{ failures . Count } task(s) failed.") ;
1203
+ DeleteMaterialResources ( ) ;
1204
+ }
1205
+
1206
+ private void CreateMaterialResources ( )
1207
+ {
1208
+ using ( var s = OpenSession ( ) )
1209
+ using ( var tx = s . BeginTransaction ( ) )
1210
+ {
1211
+ s . Save ( new MaterialResource ( "m1" , "18" , MaterialResource . MaterialState . Available ) ) ;
1212
+ s . Save ( new MaterialResource ( "m2" , "19" , MaterialResource . MaterialState . Reserved ) ) ;
1213
+ s . Save ( new MaterialResource ( "m3" , "20" , MaterialResource . MaterialState . Discarded ) ) ;
1214
+ tx . Commit ( ) ;
1215
+ }
1216
+ }
1217
+
1218
+ private void DeleteMaterialResources ( )
1219
+ {
1220
+ using ( var s = OpenSession ( ) )
1221
+ using ( var tx = s . BeginTransaction ( ) )
1222
+ {
1223
+ s . CreateQuery ( "delete from MaterialResource" ) . ExecuteUpdate ( ) ;
1224
+ tx . Commit ( ) ;
1225
+ }
1226
+ }
1017
1227
}
1228
+
1018
1229
public class ForNh1725
1019
1230
{
1020
1231
public string Description { get ; set ; }
0 commit comments