2003-11-25 Tim Coleman <tim@timcoleman.com>
[mono.git] / mcs / class / System.Data / System.Data / ExpressionElement.cs
1 //\r
2 // System.Data.ExpressionElement \r
3 //\r
4 // Author:\r
5 //   Ville Palo <vi64pa@kolumbus.fi>\r
6 //\r
7 // Copyright (C) Ville Palo, 2003\r
8 //\r
9 // TODO: - Some functionelements and aggregates.\r
10 //       - New parsing style.\r
11 //       - Exceptions\r
12 //\r
13 \r
14 using System;\r
15 using System.Data;\r
16 using System.Reflection;\r
17 \r
18 using System.Collections;\r
19 \r
20 namespace System.Data\r
21 {\r
22         /// <summary>\r
23         /// The main element which includes whole expression\r
24         /// </summary>\r
25         internal class ExpressionMainElement : ExpressionElement\r
26         {\r
27                 \r
28                 #region Fields\r
29 \r
30                 enum OP {OPERATOR, OPERAND};\r
31                 enum OPERATOR_TYPE {SYMBOLIC, LITERAL, UNDEFINED};\r
32                 enum OPERAND_TYPE {NUMERIC, STRING, UNDEFINED};\r
33 \r
34                 #endregion // Fields\r
35 \r
36                 public ExpressionMainElement (string s)\r
37                 {\r
38                         s = ValidateExpression (s);\r
39                         ParseExpression (s);\r
40                 }\r
41                 \r
42                 public override bool Test (DataRow Row) {\r
43 \r
44                         foreach (ExpressionElement El in Elements) {\r
45                                 if (!El.Test (Row))\r
46                                         return false;\r
47                         }\r
48                         \r
49                         return true;\r
50                 }\r
51 \r
52                 /// <summary>\r
53                 ///  Checks syntax of expression and throws exception if needed.\r
54                 ///  Also removes whitespaces between operator elements for example: age < = 64 --> age <= 64\r
55                 /// </summary>\r
56                 private string ValidateExpression (string s)\r
57                 {                       \r
58                         //\r
59                         // TODO: find out nice way to do this. This is NOT nice way :-P\r
60                         //\r
61                         string temp = "";\r
62                         OP op = OP.OPERAND;\r
63                         OPERATOR_TYPE operatorType = OPERATOR_TYPE.UNDEFINED;\r
64 \r
65                         string strOperator = "";\r
66                         string strOperand = "";\r
67                         int quotes = 0;\r
68                         int parentheses = 0;\r
69                         string newExp = "";\r
70                         bool isDigit = false;\r
71                         bool litOperator = false;\r
72                         s = s.Trim();\r
73                         \r
74                         for (int i = 0; i < s.Length; i++) {\r
75 \r
76                                 char c = s [i];\r
77                                 \r
78                                 if (c == '\'')\r
79                                         quotes++;\r
80 \r
81                                 if ((c == '\n' || c == '\t') && quotes == 0)\r
82                                         c = ' ';\r
83 \r
84                                 if (op == OP.OPERAND && c == '(')\r
85                                         parentheses++;\r
86                                 else if (op == OP.OPERAND && c == ')')\r
87                                         parentheses--;\r
88 \r
89                                 if (c == ' ' && op ==  OP.OPERAND && (quotes % 2) == 0 && parentheses == 0) {\r
90                                         \r
91                                         op = OP.OPERATOR;\r
92                                         newExp += strOperand;\r
93                                         strOperand = "";\r
94                                         strOperator = " ";\r
95                                 }\r
96 \r
97                                 if (op == OP.OPERAND) {\r
98 \r
99                                         if (!Char.IsDigit (c) && isDigit && (quotes % 2) == 0) {\r
100 \r
101                                                 newExp += strOperand;\r
102                                                 strOperand = "";\r
103                                                 op = OP.OPERATOR;\r
104                                                 operatorType = OPERATOR_TYPE.UNDEFINED;\r
105                                         }\r
106                                         else\r
107                                                 strOperand += c;\r
108                                 }\r
109 \r
110                                 if (op == OP.OPERATOR) {\r
111 \r
112                                         isDigit = false;\r
113                                         if (operatorType == OPERATOR_TYPE.UNDEFINED) {\r
114 \r
115                                                 if (c == '<' || c == '=' || c == '>' || c == '*' || c == '/' || c == '%' \r
116                                                         || c == '-' || c == '+')\r
117 \r
118                                                         operatorType = OPERATOR_TYPE.SYMBOLIC;\r
119                                                 else if (c != ' ')\r
120                                                         operatorType = OPERATOR_TYPE.LITERAL;\r
121                                         }\r
122                                         else if (operatorType == OPERATOR_TYPE.SYMBOLIC) {\r
123 \r
124                                                 if (c != '<' && c != '=' && c != '>' && c != ' ') {\r
125                                                         \r
126                                                         // this is COPY-PASTE\r
127                                                         op = OP.OPERAND;\r
128                                                         if (!newExp.EndsWith (" ") && !strOperator.StartsWith (" ")) \r
129                                                                 strOperator = " " + strOperator;\r
130 \r
131                                                         newExp += strOperator;\r
132 \r
133                                                         if (Char.IsDigit (c))\r
134                                                                 isDigit = true;\r
135                                                                 \r
136                                                         strOperand = c.ToString ();\r
137                                                         \r
138                                                         strOperator = "";\r
139                                                         continue;\r
140                                                 }\r
141                                         }\r
142 \r
143                                         if (operatorType == OPERATOR_TYPE.LITERAL && c == ' ') {\r
144                                                 op = OP.OPERAND;\r
145                                                 newExp += strOperator;\r
146                                                 strOperand += " ";\r
147                                                 strOperator = "";\r
148                                         }\r
149 \r
150 \r
151                                         if (Char.IsDigit (c) && operatorType != OPERATOR_TYPE.LITERAL) {\r
152 \r
153                                                 op = OP.OPERAND;\r
154 \r
155                                                 if (!newExp.EndsWith (" ") && !strOperator.StartsWith (" "))\r
156                                                         strOperator = " " + strOperator;\r
157                                                 newExp += strOperator;\r
158                                                 strOperand = c.ToString ();\r
159                                                 isDigit = true;\r
160                                                 strOperator = "";\r
161                                         }\r
162 \r
163                                         else if (c != ' ')\r
164                                                 strOperator += c;                                       \r
165                                 }\r
166                         }\r
167 \r
168                         if (op == OP.OPERATOR)\r
169                                 throw new SyntaxErrorException (\r
170                                         "Missing operand after '" + strOperator + "' operator");\r
171                         else\r
172                                 newExp += strOperand;\r
173 \r
174                         return newExp;\r
175                 }\r
176         }\r
177 \r
178         //\r
179         // O_P_E_R_A_T_O_R_S\r
180         //\r
181 \r
182         /// <summary>\r
183         ///  Class for =\r
184         /// </summary>\r
185         internal class ExpressionEquals : ExpressionElement\r
186         {       \r
187 \r
188                 public ExpressionEquals (string exp1, string exp2) \r
189                 {       \r
190                         this.exp1 = exp1;\r
191                         this.exp2 = exp2;\r
192                         ParseExpression (exp1);\r
193                         ParseExpression (exp2);\r
194                 }\r
195 \r
196                 public override bool Test (DataRow Row) {\r
197                         \r
198                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
199                         ExpressionElement E2 = (ExpressionElement)Elements [1];\r
200 \r
201                         return ExpressionElement.Compare (E1, E2, Row) == 0;\r
202                 }\r
203         }\r
204 \r
205         /// <summary>\r
206         ///  Class for <\r
207         /// </summary>\r
208         internal class ExpressionLessThan : ExpressionElement\r
209         {       \r
210 \r
211                 public ExpressionLessThan (string exp1, string exp2) \r
212                 {       \r
213                         this.exp1 = exp1;\r
214                         this.exp2 = exp2;\r
215                         ParseExpression (exp1);\r
216                         ParseExpression (exp2);\r
217                 }\r
218 \r
219                 public override bool Test (DataRow Row) {\r
220                                                                 \r
221                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
222                         ExpressionElement E2 = (ExpressionElement)Elements [1];\r
223                                            \r
224                         return ExpressionElement.Compare (E1, E2, Row) < 0;\r
225                 }\r
226         }\r
227 \r
228         /// <summary>\r
229         ///  Class for <=\r
230         /// </summary>\r
231         internal class ExpressionLessThanOrEqual : ExpressionElement\r
232         {       \r
233 \r
234                 public ExpressionLessThanOrEqual (string exp1, string exp2) \r
235                 {       \r
236                         this.exp1 = exp1;\r
237                         this.exp2 = exp2;\r
238                         ParseExpression (exp1);\r
239                         ParseExpression (exp2);\r
240                 }\r
241 \r
242                 public override bool Test (DataRow Row) {\r
243 \r
244                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
245                         ExpressionElement E2 = (ExpressionElement)Elements [1];\r
246 \r
247                         return ExpressionElement.Compare (E1, E2, Row) <= 0;\r
248                 }\r
249         }\r
250 \r
251         /// <summary>\r
252         ///  Class for >\r
253         /// </summary>\r
254         internal class ExpressionGreaterThan : ExpressionElement\r
255         {       \r
256 \r
257                 public ExpressionGreaterThan (string exp1, string exp2) \r
258                 {       \r
259                         this.exp1 = exp1;\r
260                         this.exp2 = exp2;\r
261                         ParseExpression (exp1);\r
262                         ParseExpression (exp2);\r
263                 }\r
264 \r
265                 public override bool Test (DataRow Row) {\r
266                         \r
267                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
268                         ExpressionElement E2 = (ExpressionElement)Elements [1];\r
269 \r
270                         return ExpressionElement.Compare (E1, E2, Row) > 0;\r
271                 }\r
272         }\r
273 \r
274         /// <summary>\r
275         ///  Class for >=\r
276         /// </summary>\r
277         internal class ExpressionGreaterThanOrEqual : ExpressionElement\r
278         {       \r
279 \r
280                 public ExpressionGreaterThanOrEqual (string exp1, string exp2) \r
281                 {       \r
282                         this.exp1 = exp1;\r
283                         this.exp2 = exp2;\r
284                         ParseExpression (exp1);\r
285                         ParseExpression (exp2);\r
286                 }\r
287 \r
288                 public override bool Test (DataRow Row) {\r
289 \r
290                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
291                         ExpressionElement E2 = (ExpressionElement)Elements [1];\r
292 \r
293                         return ExpressionElement.Compare (E1, E2, Row) >= 0;\r
294                 }\r
295         }\r
296 \r
297         /// <summary>\r
298         ///  Class for <>\r
299         /// </summary>\r
300         internal class ExpressionUnequals : ExpressionElement\r
301         {       \r
302 \r
303                 public ExpressionUnequals (string exp1, string exp2) \r
304                 {       \r
305                         this.exp1 = exp1;\r
306                         this.exp2 = exp2;\r
307                         ParseExpression (exp1);\r
308                         ParseExpression (exp2);\r
309                 }\r
310 \r
311                 public override bool Test (DataRow Row) {\r
312                         \r
313                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
314                         ExpressionElement E2 = (ExpressionElement)Elements [1];\r
315 \r
316                         return ExpressionElement.Compare (E1, E2, Row) != 0;\r
317                 }\r
318         }\r
319 \r
320 \r
321         /// <summary>\r
322         ///  Class for LIKE-operator\r
323         /// </summary>\r
324         internal class ExpressionLike : ExpressionElement\r
325         {       \r
326 \r
327                 public ExpressionLike (string exp1, string exp2) \r
328                 {\r
329                         ParseExpression (exp1);\r
330                         ParseExpression (exp2);\r
331                 }\r
332 \r
333                 public override bool Test (DataRow Row) {\r
334 \r
335                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
336                         ExpressionElement E2 = (ExpressionElement)Elements [1];\r
337                         object value1 = E1.Result (Row);\r
338                         object value2 = E2.Result (Row);\r
339                         \r
340                         if (value1.GetType () != typeof (string) || value2.GetType () != typeof (string))\r
341                                 throw new Exception (); // TODO: what exception\r
342                         \r
343                         string operand1 = value1.ToString ();\r
344                         string operand2 = value2.ToString ();\r
345 \r
346                         // find out is there wildcards like * or %.\r
347                         while (operand2.EndsWith ("*") || operand2.EndsWith ("%"))                             \r
348                                 operand2 = operand2.Remove (operand2.Length - 1, 1);\r
349                         while (operand2.StartsWith ("*") || operand2.StartsWith ("%"))\r
350                                 operand2 = operand2.Remove (0, 1);\r
351 \r
352                         int oldIndex = 0;\r
353                         int indexOf = -1;\r
354 \r
355                         indexOf = operand2.IndexOf ("*");\r
356                         while (indexOf != -1) {\r
357 \r
358                                 oldIndex = indexOf + 1;\r
359                                 if (operand2 [indexOf + 1] != ']' || operand2 [indexOf - 1] != '[')\r
360                                         throw new EvaluateException ("Error in Like operator: ther string pattern " + operand1 + " is invalid");\r
361                                 else {\r
362                                         operand2 = operand2.Remove (indexOf + 1, 1);\r
363                                         operand2 = operand2.Remove (indexOf -1, 1);\r
364                                         oldIndex--;\r
365                                 }\r
366                                         \r
367                                 indexOf = operand2.IndexOf ("*", oldIndex);\r
368                         }\r
369 \r
370                         oldIndex = 0;\r
371                         indexOf = operand2.IndexOf ("%");\r
372                         while (indexOf != -1) {\r
373 \r
374                                 oldIndex = indexOf + 1;\r
375                                 \r
376                                 if (operand2 [indexOf + 1] != ']' || operand2 [indexOf - 1] != '[')\r
377                                         throw new EvaluateException ("Error in Like operator: ther string pattern " + operand2 + " is invalid");\r
378                                 else {\r
379                                         operand2 = operand2.Remove (indexOf + 1, 1);\r
380                                         operand2 = operand2.Remove (indexOf -1, 1);                                     \r
381                                         oldIndex--;\r
382                                 }\r
383 \r
384                                 indexOf = operand2.IndexOf ("%", oldIndex);\r
385                         }\r
386 \r
387                         int len2 = operand2.Length;\r
388                         int startIndex = 0;\r
389                         while ((startIndex + len2) <= operand1.Length) {\r
390                                 if (String.Compare (operand1.Substring (startIndex, len2), operand2, !Row.Table.CaseSensitive) == 0)\r
391                                         return true;\r
392                                 startIndex++;\r
393                         }\r
394 \r
395                         return false;\r
396                 }\r
397         }\r
398 \r
399 \r
400         /// <summary>\r
401         ///  Class for OR\r
402         /// </summary>\r
403         internal class ExpressionOr : ExpressionElement\r
404         {                               \r
405                 public ExpressionOr (string exp1, string exp2)\r
406                 {\r
407                         ParseExpression (exp1);\r
408                         ParseExpression (exp2);\r
409                 }\r
410 \r
411                 public override bool Test (DataRow Row) \r
412                 {                       \r
413                         foreach (ExpressionElement El in Elements) {\r
414                                 if (El.Test (Row))\r
415                                         return true;\r
416                         }\r
417                         \r
418                         return false;\r
419                 }                               \r
420         }\r
421                 \r
422         /// <summary>\r
423         ///  Class for AND\r
424         /// </summary>\r
425         internal class ExpressionAnd : ExpressionElement\r
426         {                               \r
427                 public ExpressionAnd (string exp1, string exp2)\r
428                 {\r
429                         ParseExpression (exp1);\r
430                         ParseExpression (exp2);\r
431                 }\r
432                \r
433                 public override object Result (DataRow Row) {\r
434                         \r
435                         return Test(Row);\r
436                 }\r
437 \r
438                 public override bool Test (DataRow Row) \r
439                 {\r
440                         foreach (ExpressionElement El in Elements) {\r
441                                 if (!El.Test (Row))\r
442                                         return false;\r
443                         }\r
444                         \r
445                         return true;\r
446                 }                               \r
447         }\r
448 \r
449 \r
450         //\r
451         // A_R_I_T_H_M_E_T_I_C  O_P_E_R_A_T_O_R_S\r
452         //\r
453 \r
454         /// <summary>\r
455         ///  Class for +\r
456         /// </summary>\r
457         internal class ExpressionAddition : ExpressionElement\r
458         {\r
459                 public ExpressionAddition (string exp1, string exp2)\r
460                 {                       \r
461                         this.exp1 = exp1;\r
462                         this.exp2 = exp2;\r
463                         ParseExpression (exp1);\r
464                         ParseExpression (exp2);\r
465                 }\r
466                 \r
467                 public override Type ResultType (DataRow Row)\r
468                 {\r
469                         Type ResultType = typeof (string);\r
470                         ExpressionElement exp1Temp = ((ExpressionElement)Elements [0]);\r
471                         ExpressionElement exp2Temp = ((ExpressionElement)Elements [1]);\r
472 \r
473                         if (exp1Temp.ResultType (Row) == typeof (string) || exp2Temp.ResultType (Row) == typeof (string))\r
474                                 ResultType = typeof (string);\r
475 \r
476                         else if (exp1Temp.ResultType (Row) == typeof (long) || exp2Temp.ResultType (Row) == typeof (long))\r
477                                 ResultType = typeof (long);\r
478 \r
479                         else if (exp1Temp.ResultType (Row) == typeof (int) || exp2Temp.ResultType (Row) == typeof (int))\r
480                                 ResultType = typeof (int);\r
481 \r
482                         return ResultType;\r
483                 }\r
484 \r
485                 public override object Result (DataRow Row) \r
486                 {\r
487                         return CalculateResult (Row);\r
488                 }\r
489                 \r
490                 protected override object Calculate (object value1, object value2, Type TempType) \r
491                 {\r
492                         object Result = null;                   \r
493 \r
494                         if (TempType == typeof (string))\r
495                                 Result = (string)value1 + (string)value2;\r
496                         else if (TempType == typeof (long))\r
497                                 Result = (long)value1 + (long)value2;\r
498                         else if (TempType == typeof (int))\r
499                                 Result = (int)value1 + (int)value2;\r
500                         else if (TempType == typeof (short))\r
501                                 Result = (short)value1 + (short)value2;\r
502                         else if (TempType == typeof (ulong))\r
503                                         Result = (ulong)value1 + (ulong)value2;\r
504                         else if (TempType == typeof (uint))\r
505                                 Result = (uint)value1 + (uint)value2;\r
506                         else if (TempType == typeof (ushort))\r
507                                 Result = (ushort)value1 + (ushort)value2;\r
508                         else if (TempType == typeof (byte))\r
509                                 Result = (byte)value1 + (byte)value2;\r
510                         else if (TempType == typeof (sbyte))\r
511                                 Result = (sbyte)value1 + (sbyte)value2;\r
512                         // FIXME:\r
513                         //else if (TempType == typeof (bool))\r
514                         //      Result = (bool)value1 + (bool)value2;\r
515                         else if (TempType == typeof (float))\r
516                                 Result = (float)value1 + (float)value2;\r
517                         else if (TempType == typeof (double))\r
518                                 Result = (double)value1 + (double)value2;\r
519                         else if (TempType == typeof (decimal))\r
520                                 Result = (decimal)value1 + (decimal)value2;\r
521                         // FIXME:\r
522                         //else if (TempType == typeof (DateTime))\r
523                         //      Result = (DateTime)value1 + (DateTime)value2;\r
524                         \r
525                         return Result;\r
526                 }\r
527 \r
528 \r
529                 // This method is shouldnt never invoked\r
530                 public override bool Test (DataRow Row)\r
531                 {\r
532                         throw new EvaluateException ();\r
533                 }\r
534         }\r
535 \r
536         /// <summary>\r
537         ///  Class for -\r
538         /// </summary>\r
539         internal class ExpressionSubtraction : ExpressionElement\r
540         {\r
541                 public ExpressionSubtraction (string exp1, string exp2)\r
542                 {                       \r
543                         this.exp1 = exp1;\r
544                         this.exp2 = exp2;\r
545                         ParseExpression (exp1);\r
546                         ParseExpression (exp2);\r
547                 }\r
548                 \r
549                 public override object Result (DataRow Row) \r
550                 {                       \r
551                         return CalculateResult (Row);\r
552                 }\r
553                 \r
554                 // This method is shouldnt never invoked\r
555                 public override bool Test (DataRow Row)\r
556                 {\r
557                         throw new EvaluateException ();\r
558                 }\r
559 \r
560                 protected override object Calculate (object value1, object value2, Type TempType) \r
561                 {\r
562                         object Result = null;                   \r
563 \r
564                         // FIXME:\r
565                         //if (TempType == typeof (string))\r
566                         //      Result = (string)value1 - (string)value2;\r
567                         if (TempType == typeof (long))\r
568                                 Result = (long)value1 - (long)value2;\r
569                         else if (TempType == typeof (int))\r
570                                 Result = (int)value1 - (int)value2;\r
571                         else if (TempType == typeof (short))\r
572                                 Result = (short)value1 - (short)value2;\r
573                         else if (TempType == typeof (ulong))\r
574                                         Result = (ulong)value1 + (ulong)value2;\r
575                         else if (TempType == typeof (uint))\r
576                                 Result = (uint)value1 - (uint)value2;\r
577                         else if (TempType == typeof (ushort))\r
578                                 Result = (ushort)value1 - (ushort)value2;\r
579                         else if (TempType == typeof (byte))\r
580                                 Result = (byte)value1 - (byte)value2;\r
581                         else if (TempType == typeof (sbyte))\r
582                                 Result = (sbyte)value1 - (sbyte)value2;\r
583                         // FIXME:\r
584                         //else if (TempType == typeof (bool))\r
585                         //      Result = (bool)value1 - (bool)value2;\r
586                         else if (TempType == typeof (float))\r
587                                 Result = (float)value1 - (float)value2;\r
588                         else if (TempType == typeof (double))\r
589                                 Result = (double)value1 - (double)value2;\r
590                         else if (TempType == typeof (decimal))\r
591                                 Result = (decimal)value1 - (decimal)value2;\r
592                         // FIXME:\r
593                         //else if (TempType == typeof (DateTime))\r
594                         //      Result = (DateTime)value1 - (DateTime)value2;\r
595                         \r
596                         return Result;\r
597                 }\r
598         }\r
599 \r
600         /// <summary>\r
601         ///  Class for *\r
602         /// </summary>\r
603         internal class ExpressionMultiply : ExpressionElement\r
604         {\r
605                 public ExpressionMultiply (string exp1, string exp2)\r
606                 {                       \r
607                         this.exp1 = exp1;\r
608                         this.exp2 = exp2;\r
609                         ParseExpression (exp1);\r
610                         ParseExpression (exp2);\r
611                 }\r
612                 \r
613                 public override Type ResultType (DataRow Row)\r
614                 {\r
615                         Type ResultType = null;\r
616                         ExpressionElement E1 = ((ExpressionElement)Elements [0]);\r
617                         ExpressionElement E2 = ((ExpressionElement)Elements [1]);\r
618                         Type t1 = E1.ResultType (Row);\r
619                         Type t2 = E2.ResultType (Row);\r
620                                 \r
621                         if (t1 == typeof (string) || t2 == typeof (string))\r
622                                 throw new EvaluateException ("Cannon perform '*' operation on " + t1.ToString () + \r
623                                                              " and " + t2.ToString ());\r
624 \r
625                         else if (t1 == typeof (long) || t2 == typeof (long))\r
626                                 ResultType = typeof (long);\r
627 \r
628                         else if (t1 == typeof (int) || t2 == typeof (int))\r
629                                 ResultType = typeof (int);\r
630 \r
631                         return ResultType;\r
632                 }\r
633 \r
634                 public override object Result (DataRow Row) \r
635                 {\r
636                         return CalculateResult (Row);\r
637                 }\r
638                 \r
639                 public override bool Test (DataRow Row)\r
640                 {\r
641                         throw new EvaluateException ();\r
642                 }\r
643 \r
644                 protected override object Calculate (object value1, object value2, Type TempType) \r
645                 {\r
646                         object Result = null;                   \r
647 \r
648                         if (TempType == typeof (long))\r
649                                 Result = (long)value1 * (long)value2;\r
650                         else if (TempType == typeof (int))\r
651                                 Result = (int)value1 * (int)value2;\r
652                         else if (TempType == typeof (short))\r
653                                 Result = (short)value1 * (short)value2;\r
654                         else if (TempType == typeof (ulong))\r
655                                 Result = (ulong)value1 * (ulong)value2;\r
656                         else if (TempType == typeof (uint))\r
657                                 Result = (uint)value1 * (uint)value2;\r
658                         else if (TempType == typeof (ushort))\r
659                                 Result = (ushort)value1 * (ushort)value2;\r
660                         else if (TempType == typeof (byte))\r
661                                 Result = (byte)value1 * (byte)value2;\r
662                         else if (TempType == typeof (sbyte))\r
663                                 Result = (sbyte)value1 * (sbyte)value2;\r
664                         // FIXME:\r
665                         //else if (TempType == typeof (bool))\r
666                         //      Result = (bool)value1 * (bool)value2;\r
667                         else if (TempType == typeof (float))\r
668                                 Result = (float)value1 * (float)value2;\r
669                         else if (TempType == typeof (double))\r
670                                 Result = (double)value1 * (double)value2;\r
671                         else if (TempType == typeof (decimal))\r
672                                 Result = (decimal)value1 * (decimal)value2;\r
673                         // FIXME:\r
674                         //else if (TempType == typeof (DateTime))\r
675                         //      Result = (DateTime)value1 * (DateTime)value2;\r
676                         \r
677                         return Result;\r
678                 }\r
679 \r
680         }\r
681 \r
682         /// <summary>\r
683         ///  Class for *\r
684         /// </summary>\r
685         internal class ExpressionDivide : ExpressionElement\r
686         {\r
687                 public ExpressionDivide (string exp1, string exp2)\r
688                 {                       \r
689                         this.exp1 = exp1;\r
690                         this.exp2 = exp2;\r
691                         ParseExpression (exp1);\r
692                         ParseExpression (exp2);\r
693                 }\r
694                 \r
695                 public override object Result (DataRow Row) \r
696                 {\r
697                         return CalculateResult (Row);\r
698                 }\r
699                 \r
700                 // This method is shouldnt never invoked\r
701                 public override bool Test (DataRow Row)\r
702                 {\r
703                         throw new EvaluateException ();\r
704                 }\r
705 \r
706                 protected  override object Calculate (object value1, object value2, Type TempType) \r
707                 {\r
708                         object Result = null;                   \r
709 \r
710                         if (TempType == typeof (long))\r
711                                 Result = (long)value1 / (long)value2;\r
712                         // FIXME: \r
713                         //else if (TempType == typeof (int))\r
714                         //      Result = (string)value1 / (string)value2;\r
715                         else if (TempType == typeof (int))\r
716                                 Result = (int)value1 / (int)value2;\r
717                         else if (TempType == typeof (short))\r
718                                 Result = (short)value1 / (short)value2;\r
719                         else if (TempType == typeof (ulong))\r
720                                 Result = (ulong)value1 / (ulong)value2;\r
721                         else if (TempType == typeof (uint))\r
722                                 Result = (uint)value1 / (uint)value2;\r
723                         else if (TempType == typeof (ushort))\r
724                                 Result = (ushort)value1 / (ushort)value2;\r
725                         else if (TempType == typeof (byte))\r
726                                 Result = (byte)value1 / (byte)value2;\r
727                         else if (TempType == typeof (sbyte))\r
728                                 Result = (sbyte)value1 / (sbyte)value2;\r
729                         // FIXME:\r
730                         //else if (TempType == typeof (bool))\r
731                         //      Result = (bool)value1 // (bool)value2;\r
732                         else if (TempType == typeof (float))\r
733                                 Result = (float)value1 / (float)value2;\r
734                         else if (TempType == typeof (double))\r
735                                 Result = (double)value1 / (double)value2;\r
736                         else if (TempType == typeof (decimal))\r
737                                 Result = (decimal)value1 / (decimal)value2;\r
738                         // FIXME:\r
739                         //else if (TempType == typeof (DateTime))\r
740                         //      Result = (DateTime)value1 / (DateTime)value2;\r
741                         \r
742                         return Result;\r
743                 }\r
744         }\r
745 \r
746         /// <summary>\r
747         ///  Class for *\r
748         /// </summary>\r
749         internal class ExpressionModulus : ExpressionElement\r
750         {\r
751                 public ExpressionModulus (string exp1, string exp2)\r
752                 {                       \r
753                         this.exp1 = exp1;\r
754                         this.exp2 = exp2;\r
755                         ParseExpression (exp1);\r
756                         ParseExpression (exp2);\r
757                 }\r
758                 \r
759                 public override object Result (DataRow Row) \r
760                 {\r
761                         return CalculateResult (Row);\r
762                 }\r
763                 \r
764                 // This method is shouldnt never invoked\r
765                 public override bool Test (DataRow Row)\r
766                 {\r
767                         throw new EvaluateException ();\r
768                 }\r
769 \r
770                 protected  override object Calculate (object value1, object value2, Type TempType) \r
771                 {\r
772                         object Result = null;                   \r
773 \r
774                         if (TempType == typeof (long))\r
775                                 Result = (long)value1 % (long)value2;\r
776                         // FIXME: \r
777                         //else if (TempType == typeof (int))\r
778                         //      Result = (string)value1 % (string)value2;\r
779                         else if (TempType == typeof (int))\r
780                                 Result = (int)value1 % (int)value2;\r
781                         else if (TempType == typeof (short))\r
782                                 Result = (short)value1 % (short)value2;\r
783                         else if (TempType == typeof (ulong))\r
784                                 Result = (ulong)value1 % (ulong)value2;\r
785                         else if (TempType == typeof (uint))\r
786                                 Result = (uint)value1 % (uint)value2;\r
787                         else if (TempType == typeof (ushort))\r
788                                 Result = (ushort)value1 % (ushort)value2;\r
789                         else if (TempType == typeof (byte))\r
790                                 Result = (byte)value1 % (byte)value2;\r
791                         else if (TempType == typeof (sbyte))\r
792                                 Result = (sbyte)value1 % (sbyte)value2;\r
793                         // FIXME:\r
794                         //else if (TempType == typeof (bool))\r
795                         //      Result = (bool)value1 // (bool)value2;\r
796                         else if (TempType == typeof (float))\r
797                                 Result = (float)value1 % (float)value2;\r
798                         else if (TempType == typeof (double))\r
799                                 Result = (double)value1 % (double)value2;\r
800                         else if (TempType == typeof (decimal))\r
801                                 Result = (decimal)value1 % (decimal)value2;\r
802                         // FIXME:\r
803                         //else if (TempType == typeof (DateTime))\r
804                         //      Result = (DateTime)value1 / (DateTime)value2;\r
805                         \r
806                         return Result;\r
807                 }\r
808         }\r
809 \r
810         //\r
811         // _____A_G_G_R_E_G_A_T_E_S_____\r
812         //\r
813 \r
814         internal class ExpressionAggregate : ExpressionElement\r
815         {\r
816                 //public override object Result (DataRow Row) \r
817                 //{\r
818                 //      return null;\r
819                 //}\r
820                 \r
821                 public override bool Test (DataRow Row)\r
822                 {\r
823                         throw new EvaluateException ();\r
824                 }\r
825 \r
826                 protected virtual void ParseParameters (string s)\r
827                 {\r
828                         string stemp = s.ToLower ();\r
829                         bool inString = false;\r
830                         string p1 = null;\r
831 \r
832                         // find (\r
833                         while (!s.StartsWith ("("))\r
834                                 s = s.Remove (0, 1);\r
835                         \r
836                         // remove (\r
837                         s = s.Remove (0, 1);\r
838 \r
839                         int parentheses = 0;\r
840                         for (int i = 0; i < s.Length; i++) {\r
841 \r
842                                 if (s [i] == '\'')\r
843                                         inString = !inString;\r
844                                 else if (s [i] == '(')\r
845                                         parentheses++;\r
846                                 else if (s [i] == ')')\r
847                                         parentheses--;\r
848 \r
849                                 if ((s [i] == ',' ||  s [i] == ')') && !inString && parentheses == -1) { // Parameter changed\r
850 \r
851                                         if (p1 == null) {\r
852                                                 p1 = s.Substring (0, i);\r
853                                                 break;\r
854                                         }\r
855                                 }\r
856                         }\r
857 \r
858                         if (p1 == null)\r
859                                 throw new Exception ();\r
860 \r
861                         ParseExpression (p1);           \r
862                 }\r
863                 \r
864         }\r
865 \r
866         /// <summary>\r
867         ///  Class for Sum (column_Name)\r
868         /// </summary\r
869         internal class ExpressionSum : ExpressionAggregate\r
870         {\r
871                 public ExpressionSum (string exp1)\r
872                 {\r
873                         ParseParameters (exp1);\r
874                 }\r
875 \r
876                 public override object Result (DataRow Row) \r
877                 {\r
878                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
879                         object value1 = E1.Result (Row);\r
880                         Type t1 = value1.GetType ();\r
881                         object result = null;\r
882                         \r
883                         // This could be optimized. If E1 is single element (Not child or parent) the\r
884                         // result of Sum() aggregate is allways same\r
885 \r
886                         if (E1 is ExpressionSingleElement) {\r
887                                 \r
888                                 // This should be optimized somehow\r
889                                 foreach (DataRow tempRow in Row.Table.Rows) {\r
890 \r
891                                         // TODO: other types and exceptions\r
892                                         object v = E1.Result (tempRow);\r
893                                         t1 = v.GetType ();\r
894 \r
895                                         if (v == null || v == DBNull.Value)\r
896                                                 continue;\r
897 \r
898                                         if (t1 == typeof (long)) {\r
899                                                 result = 0;\r
900                                                 result = (long)result + (long)v;\r
901                                         }\r
902                                         else if (t1 == typeof (int)) {\r
903                                                 result = 0;\r
904                                                 result = (int)result + (int)v;\r
905                                         }\r
906                                         else if (t1 == typeof (short)) {\r
907                                                 result = 0;\r
908                                                 result = (short)result + (short)v;\r
909                                         }\r
910                                         else if (t1 == typeof (double)) {\r
911                                                 result = 0;\r
912                                                 result = (double)result + (double)v;\r
913                                         }\r
914                                         else if (t1 == typeof (float)) {\r
915                                                 result = 0;\r
916                                                 result = (float)result + (float)v;\r
917                                         }\r
918                                         else\r
919                                                 throw new NotImplementedException ();\r
920                                 }\r
921                         }\r
922                         \r
923                         return result;\r
924                 }\r
925                 \r
926                 //\r
927                 // FIXME: This method is copy-paste in every Aggregate class.\r
928                 //\r
929         }\r
930 \r
931         /// <summary>\r
932         ///  Class for Avg (column_Name)\r
933         /// </summary\r
934         internal class ExpressionAvg : ExpressionAggregate\r
935         {\r
936                 public ExpressionAvg (string exp1)\r
937                 {\r
938                         ParseParameters (exp1);\r
939                 }\r
940 \r
941                 /// <summary>\r
942                 ///  This is used from ExpressionStdDev for evaluating avg.\r
943                 /// </summary>\r
944                 public ExpressionAvg (ExpressionElement E)\r
945                 {\r
946                         Elements.Add (E);\r
947                 }\r
948 \r
949                 public override object Result (DataRow Row) \r
950                 {\r
951                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
952                         object value1 = E1.Result (Row);\r
953                         Type original = value1.GetType ();\r
954                         object result = null;\r
955                         \r
956                         if (E1 is ExpressionSingleElement) {\r
957                                 \r
958                                 Type t1 = null;\r
959                                 // This should be optimized somehow\r
960                                 foreach (DataRow tempRow in Row.Table.Rows) {\r
961                                        \r
962                                         // TODO: other types and exceptions\r
963                                         object v = E1.Result (tempRow);\r
964 \r
965                                         if (v == null || v == DBNull.Value)\r
966                                                 continue;\r
967 \r
968                                         t1 = v.GetType ();\r
969 \r
970                                         if (result == null)\r
971                                                 result = 0;\r
972                                         \r
973                                         if (t1 == typeof (long)) {\r
974                                                 result = (long)result + (long)v;\r
975                                         }\r
976                                         else if (t1 == typeof (int)) {\r
977                                                 result = (int)result + (int)v;\r
978                                         }\r
979                                         else if (t1 == typeof (short)) {\r
980                                                 result = (short)result + (short)v;\r
981                                         }\r
982                                         else if (t1 == typeof (double)) {\r
983                                                 result = (double)result + (double)v;\r
984                                         }\r
985                                         else if (t1 == typeof (float)) {\r
986                                                 result = (float)result + (float)v;\r
987                                         }\r
988                                         else\r
989                                                 throw new NotImplementedException ();\r
990                                 }\r
991 \r
992                                 // TODO: types\r
993 \r
994                                 if (t1 == typeof (long))\r
995                                         result = (long)result / Row.Table.Rows.Count;\r
996                                 else if (t1 == typeof (int))\r
997                                         result = (int)result / Row.Table.Rows.Count;\r
998                                 else if (t1 == typeof (short))\r
999                                         result = (short)result / Row.Table.Rows.Count;\r
1000                                 else if (t1 == typeof (double))\r
1001                                         result = (double)result / Row.Table.Rows.Count;\r
1002                         }\r
1003                         \r
1004                         return result;\r
1005                 }               \r
1006         }\r
1007 \r
1008         /// <summary>\r
1009         ///  Class for Min (column_Name)\r
1010         /// </summary\r
1011         internal class ExpressionMin : ExpressionAggregate\r
1012         {\r
1013                 public ExpressionMin (string exp1)\r
1014                 {\r
1015                         ParseParameters (exp1);\r
1016                 }\r
1017 \r
1018                 public override object Result (DataRow Row) \r
1019                 {\r
1020                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
1021                         object value1 = E1.Result (Row);\r
1022                         Type original = value1.GetType ();\r
1023                         object result = null;\r
1024                         \r
1025                         if (E1 is ExpressionSingleElement) {\r
1026                                 \r
1027                                 Type t1 = null;\r
1028                                 // This should be optimized somehow\r
1029                                 foreach (DataRow tempRow in Row.Table.Rows) {\r
1030                                        \r
1031                                         // TODO: other types and exceptions\r
1032                                         object v = E1.Result (tempRow);\r
1033 \r
1034                                         if (v == null || v == DBNull.Value)\r
1035                                                 continue;\r
1036 \r
1037                                         t1 = v.GetType ();\r
1038 \r
1039                                         if (result == null)\r
1040                                                 result = 0;\r
1041 \r
1042                                         object CompResult = t1.InvokeMember ("CompareTo", BindingFlags.Default | \r
1043                                                                BindingFlags.InvokeMethod, null, \r
1044                                                                v, \r
1045                                                                new object [] {result});\r
1046 \r
1047                                         if ((int)CompResult < 0)\r
1048                                                 result = v;\r
1049 \r
1050                                 }\r
1051                         }\r
1052                         \r
1053                         return result;\r
1054                 }\r
1055         }\r
1056 \r
1057         /// <summary>\r
1058         ///  Class for Max (column_Name)\r
1059         /// </summary\r
1060         internal class ExpressionMax : ExpressionAggregate\r
1061         {\r
1062                 public ExpressionMax (string exp1)\r
1063                 {\r
1064                         ParseParameters (exp1);\r
1065                 }\r
1066 \r
1067                 public override object Result (DataRow Row) \r
1068                 {\r
1069                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
1070                         object value1 = E1.Result (Row);\r
1071                         Type original = value1.GetType ();\r
1072                         object result = null;\r
1073                         \r
1074                         if (E1 is ExpressionSingleElement) {\r
1075                                 \r
1076                                 Type t1 = null;\r
1077                                 // This should be optimized somehow\r
1078                                 foreach (DataRow tempRow in Row.Table.Rows) {\r
1079                                        \r
1080                                         // TODO: other types and exceptions\r
1081                                         object v = E1.Result (tempRow);\r
1082 \r
1083                                         if (v == null || v == DBNull.Value)\r
1084                                                 continue;\r
1085 \r
1086                                         t1 = v.GetType ();\r
1087 \r
1088                                         if (result == null)\r
1089                                                 result = 0;\r
1090 \r
1091                                         object CompResult = t1.InvokeMember ("CompareTo", BindingFlags.Default | \r
1092                                                                BindingFlags.InvokeMethod, null, \r
1093                                                                v, \r
1094                                                                new object [] {result});\r
1095 \r
1096                                         if ((int)CompResult > 0)\r
1097                                                 result = v;\r
1098 \r
1099                                 }\r
1100                         }\r
1101                         \r
1102                         return result;\r
1103                 }\r
1104         }\r
1105 \r
1106 \r
1107         /// <summary>\r
1108         ///  Class for count (column)\r
1109         /// </summary>\r
1110         internal class ExpressionCount : ExpressionAggregate\r
1111         {\r
1112                 public ExpressionCount (string exp1)\r
1113                 {\r
1114                         ParseParameters (exp1);\r
1115                 }\r
1116 \r
1117                 public override object Result (DataRow Row) \r
1118                 {\r
1119                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
1120                         int count = 0;\r
1121 \r
1122                         if (E1 is ExpressionSingleElement) {\r
1123                                 \r
1124                                 // This should be optimized somehow\r
1125                                 foreach (DataRow tempRow in Row.Table.Rows) {\r
1126                                        \r
1127                                         count++;\r
1128                                 }\r
1129                         }\r
1130                         \r
1131                         return count;\r
1132                 }\r
1133         }\r
1134 \r
1135 \r
1136         /// <summary>\r
1137         ///  Class for StdDev (column)\r
1138         /// </summary>\r
1139         internal class ExpressionStdev : ExpressionAggregate\r
1140         {\r
1141                 public ExpressionStdev (string exp1)\r
1142                 {               \r
1143                         ParseParameters (exp1);\r
1144                 }\r
1145                 \r
1146                 public override object Result (DataRow Row) \r
1147                 {\r
1148                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
1149                         ExpressionAvg Avg = new ExpressionAvg (E1);\r
1150 \r
1151                         object tempAvg = Avg.Result (Row);\r
1152                         double avg = 0;\r
1153                         double sum = 0;\r
1154                         double result = 0;\r
1155 \r
1156                         if (tempAvg.GetType () == typeof (int))\r
1157                                 avg = (double)(int)tempAvg;\r
1158                         \r
1159                         if (E1 is ExpressionSingleElement) {\r
1160 \r
1161                                 foreach (DataRow tempRow in Row.Table.Rows) {\r
1162 \r
1163                                        \r
1164                                         // (value - avg)²\r
1165                                         object v = E1.Result (tempRow);\r
1166 \r
1167                                         if (v == null || v == DBNull.Value)\r
1168                                                 continue;\r
1169 \r
1170                                         if (v.GetType () == typeof (long))\r
1171                                                 sum = avg - (long)v;\r
1172                                         else if (v.GetType () == typeof (int))\r
1173                                                 sum = avg - (int)v;\r
1174                                         else if (v.GetType () == typeof (short))\r
1175                                                 sum = avg - (short)v;\r
1176                                         else\r
1177                                                 throw new NotImplementedException ();\r
1178 \r
1179                                         result += Math.Pow (sum, 2);\r
1180                                 }\r
1181                                 \r
1182                                 result = result / (Row.Table.Rows.Count - 1);\r
1183                                 result = Math.Sqrt (result);\r
1184                         }\r
1185 \r
1186                         return result;\r
1187                 }               \r
1188         }\r
1189 \r
1190         /// <summary>\r
1191         ///  Class for Var (column)\r
1192         /// </summary>\r
1193         internal class ExpressionVar : ExpressionAggregate\r
1194         {\r
1195                 public ExpressionVar (string exp1)\r
1196                 {\r
1197                         ParseParameters (exp1);\r
1198                 }\r
1199                 \r
1200                 public override object Result (DataRow Row) \r
1201                 {\r
1202                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
1203                         ExpressionAvg Avg = new ExpressionAvg (E1);\r
1204 \r
1205                         object tempAvg = Avg.Result (Row);\r
1206                         double avg = 0;\r
1207                         double sum = 0;\r
1208                         double result = 0;\r
1209 \r
1210                         if (tempAvg.GetType () == typeof (int))\r
1211                                 avg = (double)(int)tempAvg;\r
1212                         \r
1213                         if (E1 is ExpressionSingleElement) {\r
1214 \r
1215                                 foreach (DataRow tempRow in Row.Table.Rows) {\r
1216 \r
1217                                        \r
1218                                         // (value - avg)²\r
1219                                         object v = E1.Result (tempRow);\r
1220 \r
1221                                         if (v == null || v == DBNull.Value)\r
1222                                                 continue;\r
1223 \r
1224                                         if (v.GetType () == typeof (long))\r
1225                                                 sum = avg - (long)v;\r
1226                                         else if (v.GetType () == typeof (int))\r
1227                                                 sum = avg - (int)v;\r
1228                                         else if (v.GetType () == typeof (short))\r
1229                                                 sum = avg - (short)v;\r
1230                                         else\r
1231                                                 throw new NotImplementedException ();\r
1232 \r
1233                                         result += Math.Pow (sum, 2);\r
1234                                 }\r
1235                                 \r
1236                                 result = result / (Row.Table.Rows.Count - 1);\r
1237                         }\r
1238 \r
1239                         return result;\r
1240                 }               \r
1241         }\r
1242 \r
1243         // \r
1244         // _____F_U_ N_C_T_I_O_N_S_______\r
1245         //\r
1246 \r
1247         /// <summary>\r
1248         ///  Class for len (string) function\r
1249         /// </summary>\r
1250         internal class ExpressionLen : ExpressionElement\r
1251         {\r
1252                 public ExpressionLen (string exp1)\r
1253                 {                       \r
1254                         _ResultType = typeof (int);\r
1255                         ParseParameters (exp1);\r
1256                 }\r
1257                 \r
1258                 public override object Result (DataRow Row) \r
1259                 {\r
1260                         ExpressionElement E1 = ((ExpressionElement)Elements [0]);\r
1261                         object value1 = E1.Result (Row);\r
1262                         \r
1263                         return value1.ToString ().Length;\r
1264                 }\r
1265                 \r
1266                 public override bool Test (DataRow Row)\r
1267                 {\r
1268                         throw new EvaluateException ();\r
1269                 }\r
1270 \r
1271                 public void ParseParameters (string s)\r
1272                 {\r
1273                         string stemp = s.ToLower ();\r
1274                         bool inString = false;\r
1275                         string p1 = null;\r
1276 \r
1277                         // find (\r
1278                         while (!s.StartsWith ("("))\r
1279                                 s = s.Remove (0, 1);\r
1280 \r
1281                         // remove (\r
1282                         s = s.Remove (0, 1);\r
1283                         int parentheses = 0;\r
1284                         for (int i = 0; i < s.Length; i++) {\r
1285 \r
1286                                 if (s [i] == '\'')\r
1287                                         inString = !inString;\r
1288                                 else if (s [i] == '(')\r
1289                                         parentheses++;\r
1290                                 else if (s [i] == ')')\r
1291                                         parentheses--;\r
1292 \r
1293                                 if ((s [i] == ',' ||  s [i] == ')') && !inString && parentheses == -1) { // Parameter changed\r
1294 \r
1295                                         if (p1 == null) {\r
1296                                                 p1 = s.Substring (0, i);\r
1297                                                 break;\r
1298                                         }\r
1299                                 }\r
1300                         }\r
1301 \r
1302                         if (p1 == null)\r
1303                                 throw new Exception ();\r
1304 \r
1305                         ParseExpression (p1);           \r
1306                 }\r
1307         }\r
1308 \r
1309         /// <summary>\r
1310         ///  Class for iif (exp1, truepart, falsepart) function\r
1311         /// </summary>\r
1312         internal class ExpressionIif : ExpressionElement\r
1313         {\r
1314                 public ExpressionIif (string exp)\r
1315                 {       \r
1316                         ParseParameters (exp);\r
1317                 }\r
1318 \r
1319                 public override object Result (DataRow Row) \r
1320                 {\r
1321                         ExpressionElement E1 = ((ExpressionElement)Elements [0]);\r
1322                         ExpressionElement E2 = ((ExpressionElement)Elements [1]);\r
1323                         ExpressionElement E3 = ((ExpressionElement)Elements [2]);\r
1324 \r
1325                         if (E1.Test (Row)) // expression\r
1326                                 return E2.Result (Row); // truepart\r
1327                         else\r
1328                                 return E3.Result (Row); // false part                   \r
1329                 }\r
1330                 \r
1331                 // This method is shouldnt never invoked\r
1332                 public override bool Test (DataRow Row)\r
1333                 {\r
1334                         throw new EvaluateException ();\r
1335                 }\r
1336 \r
1337                 public override Type ResultType (DataRow Row)\r
1338                 {                                               \r
1339                         ExpressionElement E1 = ((ExpressionElement)Elements [0]);\r
1340                         ExpressionElement E2 = ((ExpressionElement)Elements [1]);\r
1341                         ExpressionElement E3 = ((ExpressionElement)Elements [2]);\r
1342                         \r
1343                         if (E1.Test (Row)) // expression\r
1344                                 return E2.Result (Row).GetType (); // truepart\r
1345                         else\r
1346                                 return E3.Result (Row).GetType (); // false part                        \r
1347                 }\r
1348 \r
1349                 /// <summary>\r
1350                 ///  Parses expressions in parameters (exp, truepart, falsepart)\r
1351                 /// </summary>\r
1352                 private void ParseParameters (string s)\r
1353                 {\r
1354                         bool inString = false;\r
1355                         string stemp = s.ToLower ();\r
1356                         string p1 = null;\r
1357                         string p2 = null;\r
1358                         string p3 = null;\r
1359                         s = s.Substring (stemp.IndexOf ("iif") + 3);\r
1360 \r
1361                         // find (\r
1362                         while (!s.StartsWith ("("))\r
1363                                 s = s.Remove (0, 1);\r
1364 \r
1365                         // remove (\r
1366                         s = s.Remove (0, 1);\r
1367                         int parentheses = 0;\r
1368                         for (int i = 0; i < s.Length; i++) {\r
1369 \r
1370                                 if (s [i] == '\'')\r
1371                                         inString = !inString;\r
1372                                 else if (s [i] == '(')\r
1373                                         parentheses++;\r
1374                                 else if (s [i] == ')')\r
1375                                         parentheses--;\r
1376 \r
1377                                 if ((s [i] == ',' && !inString && parentheses == 0) || \r
1378                                         (s [i] == ')' && i == (s.Length -1))) { // Parameter changed\r
1379 \r
1380                                         if (p1 == null) {\r
1381                                                 p1 = s.Substring (0, i);\r
1382                                                 s = s.Substring (i + 1);\r
1383                                                 i = 0;\r
1384                                         }\r
1385 \r
1386                                         else if (p2 == null) {\r
1387                                                 p2 = s.Substring (0, i);\r
1388                                                 s = s.Substring (i + 1);\r
1389                                                 i = 0;\r
1390                                         }\r
1391 \r
1392                                         else if (p3 == null) {\r
1393                                                 p3 = s.Substring (0, i);\r
1394                                                 s = s.Substring (i + 1);\r
1395                                                 i = 0;\r
1396                                         }\r
1397 \r
1398                                         else\r
1399                                                 throw new Exception (); // FIXME: What exception\r
1400                                 }\r
1401                         }\r
1402 \r
1403                         if (p1 == null || p2 == null || p3 == null)\r
1404                                 throw new Exception ();\r
1405 \r
1406                         ParseExpression (p1);\r
1407                         ParseExpression (p2);\r
1408                         ParseExpression (p3);\r
1409                 }\r
1410         }\r
1411 \r
1412         /// <summary>\r
1413         ///  Class for isnull (expression, returnvalue) function\r
1414         /// </summary>\r
1415         internal class ExpressionIsNull : ExpressionElement\r
1416         {\r
1417                 public ExpressionIsNull (string exp)\r
1418                 {                       \r
1419                         ParseParameters (exp);\r
1420                 }\r
1421                 \r
1422                 public override object Result (DataRow Row) \r
1423                 {\r
1424                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
1425                         ExpressionElement E2 = (ExpressionElement)Elements [1];\r
1426                         \r
1427                         object R1 = E1.Result (Row);\r
1428                         object value1 = null;\r
1429                         if (R1 == null || R1 == DBNull.Value)\r
1430                                 return E2.Result (Row);\r
1431                         else\r
1432                                 return R1;\r
1433                 }\r
1434 \r
1435                 public override Type ResultType (DataRow Row)\r
1436                 {\r
1437                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
1438                         ExpressionElement E2 = (ExpressionElement)Elements [1];\r
1439                         \r
1440                         object R1 = E1.Result (Row);\r
1441                         object value1 = null;\r
1442                         if (R1 == null || R1 == DBNull.Value)\r
1443                                 return E2.Result (Row).GetType ();\r
1444                         else\r
1445                                 return R1.GetType ();\r
1446                 }\r
1447                 \r
1448                 /// <summary>\r
1449                 ///  IsNull function does not return boolean value, so throw exception\r
1450                 /// </summary>\r
1451                 public override bool Test (DataRow Row)\r
1452                 {\r
1453                         throw new EvaluateException ();\r
1454                 }\r
1455 \r
1456                 /// <summary>\r
1457                 ///  Parses parameters of function and invoke ParseExpression methods\r
1458                 /// </summary>\r
1459                 private void ParseParameters (string s)\r
1460                 {\r
1461                         bool inString = false;\r
1462                         string stemp = s.ToLower ();\r
1463                         string p1 = null;\r
1464                         string p2 = null;\r
1465 \r
1466                         s = s.Substring (stemp.IndexOf ("isnull") + 6);\r
1467 \r
1468                         // find (\r
1469                         while (!s.StartsWith ("("))\r
1470                                 s = s.Remove (0, 1);\r
1471 \r
1472                         // remove (\r
1473                         s = s.Remove (0, 1);\r
1474                         int parentheses = 0;\r
1475                         for (int i = 0; i < s.Length; i++) {\r
1476 \r
1477                                 if (s [i] == '\'')\r
1478                                         inString = !inString;\r
1479                                 else if (s [i] == '(')\r
1480                                         parentheses++;\r
1481                                 else if (s [i] == ')')\r
1482                                         parentheses--;\r
1483 \r
1484                                 if ((s [i] == ',' && !inString && parentheses == 0) || \r
1485                                         (s [i] == ')' && i == (s.Length -1))) { // Parameter changed\r
1486 \r
1487                                         if (p1 == null) {\r
1488                                                 p1 = s.Substring (0, i);\r
1489                                                 s = s.Substring (i + 1);\r
1490                                                 i = 0;\r
1491                                         }\r
1492 \r
1493                                         else if (p2 == null) {\r
1494                                                 p2 = s.Substring (0, i);\r
1495                                                 s = s.Substring (i + 1);\r
1496                                                 i = 0;\r
1497                                         }\r
1498 \r
1499                                         else\r
1500                                                 throw new Exception (); // FIXME: What exception\r
1501                                 }\r
1502                         }\r
1503 \r
1504                         if (p1 == null || p2 == null)\r
1505                                 throw new Exception ();\r
1506 \r
1507                         ParseExpression (p1);\r
1508                         ParseExpression (p2);\r
1509                 }\r
1510         }\r
1511 \r
1512         /// <summary>\r
1513         ///  Class for Substring (expression, start, length) function\r
1514         /// </summary>\r
1515         internal class ExpressionSubstring : ExpressionElement\r
1516         {\r
1517                 public ExpressionSubstring (string exp)\r
1518                 {                       \r
1519                         ParseParameters (exp);\r
1520                         _ResultType = typeof (string);\r
1521                 }\r
1522                 \r
1523                 public override object Result (DataRow Row) \r
1524                 {\r
1525                         ExpressionElement E1 = (ExpressionElement)Elements [0];\r
1526                         ExpressionElement E2 = (ExpressionElement)Elements [1];\r
1527                         ExpressionElement E3 = (ExpressionElement)Elements [2];\r
1528                         \r
1529                         object value1 = E1.Result (Row);\r
1530                         object value2 = E2.Result (Row);\r
1531                         object value3 = E3.Result (Row);\r
1532                         Type t1 = value1.GetType ();\r
1533                         Type t2 = value2.GetType ();\r
1534                         Type t3 = value3.GetType ();\r
1535 \r
1536                         if (value1 == null || value2 == null || value3 == null \r
1537                             || value1 == DBNull.Value || value2 == DBNull.Value || value3 == DBNull.Value)\r
1538                                 return string.Empty;\r
1539 \r
1540                         if (t1 != typeof (string))\r
1541                                 throw new Exception (); // FIXME: what exception\r
1542                         else if (t2 != typeof (int))\r
1543                                 throw new EvaluateException ("Type mismatch is function argument: Substring (), argument 2, excepted System.Int32");\r
1544                         else if (t3 != typeof (int))\r
1545                                 throw new EvaluateException ("Type mismatch is function argument: Substring (), argument 3, excepted System.Int32");\r
1546 \r
1547                         string str = value1.ToString ();\r
1548                         int start = (int)value2;\r
1549                         int length = (int)value3;\r
1550 \r
1551                         if (str.Length < start)\r
1552                                 str =  string.Empty;\r
1553                         else {\r
1554                                 if ((start + length - 1) > str.Length)\r
1555                                         str = str.Substring (start - 1);\r
1556                                 else\r
1557                                         str = str.Substring (start - 1, length);\r
1558                         }\r
1559 \r
1560                         return str;\r
1561                 }\r
1562 \r
1563                 /// <summary>\r
1564                 ///  IsNull function does not return boolean value, so throw exception\r
1565                 /// </summary>\r
1566                 public override bool Test (DataRow Row)\r
1567                 {\r
1568                         throw new EvaluateException ();\r
1569                 }\r
1570 \r
1571                 /// <summary>\r
1572                 ///  Parses parameters of function and invoke ParseExpression methods\r
1573                 /// </summary>\r
1574                 private void ParseParameters (string s)\r
1575                 {\r
1576                         bool inString = false;\r
1577                         string stemp = s.ToLower ();\r
1578                         string p1 = null;\r
1579                         string p2 = null;\r
1580                         string p3 = null;\r
1581 \r
1582                         s = s.Substring (stemp.IndexOf ("substring") + 9);\r
1583 \r
1584                         // find (\r
1585                         while (!s.StartsWith ("("))\r
1586                                 s = s.Remove (0, 1);\r
1587 \r
1588                         // remove (\r
1589                         s = s.Remove (0, 1);\r
1590                         int parentheses = 0;\r
1591                         for (int i = 0; i < s.Length; i++) {\r
1592 \r
1593                                 if (s [i] == '\'')\r
1594                                         inString = !inString;\r
1595                                 else if (s [i] == '(')\r
1596                                         parentheses++;\r
1597                                 else if (s [i] == ')')\r
1598                                         parentheses--;\r
1599 \r
1600 \r
1601                                 if ((s [i] == ',' && !inString && parentheses == 0) || \r
1602                                         (s [i] == ')' && i == (s.Length -1))) { // Parameter changed\r
1603 \r
1604                                         if (p1 == null) {\r
1605                                                 p1 = s.Substring (0, i);\r
1606                                                 s = s.Substring (i + 1);\r
1607                                                 i = 0;\r
1608                                         }\r
1609 \r
1610                                         else if (p2 == null) {\r
1611                                                 p2 = s.Substring (0, i);\r
1612                                                 s = s.Substring (i + 1);\r
1613                                                 i = 0;\r
1614                                         }\r
1615 \r
1616                                         else if (p3 == null) {\r
1617                                                 p3 = s.Substring (0, i);\r
1618                                                 s = s.Substring (i + 1);\r
1619                                                 i = 0;\r
1620                                         }\r
1621 \r
1622                                         else\r
1623                                                 throw new Exception (); // FIXME: What exception\r
1624                                 }\r
1625                         }\r
1626 \r
1627                         if (p1 == null || p2 == null)\r
1628                                 throw new Exception ();\r
1629 \r
1630                         ParseExpression (p1);\r
1631                         ParseExpression (p2);\r
1632                         ParseExpression (p3);                   \r
1633                 }\r
1634         }\r
1635 \r
1636         /// <summary>\r
1637         ///  Class for In (exp, exp, exp, ...) function\r
1638         /// </summary>\r
1639         internal class ExpressionIn : ExpressionElement\r
1640         {\r
1641                 public ExpressionIn (string exp1, string exp2)\r
1642                 {       \r
1643                         ParseExpression(exp1);\r
1644                         ParseParameters (exp2);\r
1645                 }\r
1646 \r
1647                 /// <summary>\r
1648                 ///  IsNull function does not return boolean value, so throw exception\r
1649                 /// </summary>\r
1650                 public override bool Test (DataRow Row) \r
1651                 {\r
1652                         ExpressionElement E;\r
1653                         ExpressionElement columnElement = (ExpressionElement)Elements [0];\r
1654 \r
1655                         for (int i = 1; i < Elements.Count; i++)\r
1656                         {\r
1657                                 E = (ExpressionElement)Elements [i];\r
1658                                 if(ExpressionElement.Compare (columnElement, E, Row) == 0)\r
1659                                         return true;\r
1660                         }\r
1661                         return false;\r
1662                 }\r
1663 \r
1664                 /// <summary>\r
1665                 ///  Parses parameters of function and invoke ParseExpression methods\r
1666                 /// </summary>\r
1667                 private void ParseParameters (string s)\r
1668                 {\r
1669                         bool inString = false;\r
1670                         ArrayList parameters = new ArrayList();\r
1671                         \r
1672                         // find (\r
1673                         while (!s.StartsWith ("("))\r
1674                                 s = s.Remove (0, 1);\r
1675 \r
1676                         // remove (\r
1677                         s = s.Remove (0, 1);\r
1678                         int parentheses = 0;\r
1679                         for (int i = 0; i < s.Length; i++) \r
1680                         {\r
1681 \r
1682                                 if (s [i] == '\'')\r
1683                                         inString = !inString;\r
1684                                 else if (s [i] == '(')\r
1685                                         parentheses++;\r
1686                                 else if (s [i] == ')')\r
1687                                         parentheses--;\r
1688 \r
1689 \r
1690                                 if ((s [i] == ',' && !inString && parentheses == 0) || \r
1691                                         (s [i] == ')' && i == (s.Length -1))) \r
1692                                 {\r
1693                                         parameters.Add(s.Substring (0, i));\r
1694                                         s = s.Substring (i + 1);\r
1695                                         i = 0;\r
1696                                 }\r
1697                         }\r
1698                         \r
1699                         for (int i = 0; i < parameters.Count; i++)\r
1700                                 ParseExpression((string)parameters[i]);\r
1701                 }\r
1702         }\r
1703 \r
1704         /// <summary>\r
1705         ///  Class for just one element for example string, int, ...\r
1706         /// </summary>\r
1707         internal class ExpressionSingleElement : ExpressionElement\r
1708         {               \r
1709                 private object Element = null;\r
1710                 \r
1711                 public ExpressionSingleElement (string s)\r
1712                 {\r
1713                         // TODO: Every type should be checked\r
1714                         if (s.StartsWith ("'") && s.EndsWith ("'")) {\r
1715                                 Element = s.Substring (1, s.Length - 2);\r
1716                                 _ResultType = typeof (string);\r
1717                         }\r
1718                         else if (!Char.IsDigit (s [0]) && s [0] != '-' && s [0] != '+') {\r
1719                                 Element = s;\r
1720                                 _ResultType = typeof (DataColumn);\r
1721                         }\r
1722                         else if (s.StartsWith ("#") && s.EndsWith ("#")) {\r
1723                                 Element = DateTime.Parse (s.Substring (1, s.Length - 2));\r
1724                                 _ResultType = typeof (DateTime);\r
1725                         }\r
1726                         else {\r
1727                                 try {\r
1728                                         Element = int.Parse (s);\r
1729                                         _ResultType = typeof (int);\r
1730                                 } catch {\r
1731                                         Element = Decimal.Parse (s);\r
1732                                         _ResultType = typeof (Decimal);\r
1733                                 }\r
1734                         }                               \r
1735                 }\r
1736 \r
1737                 public override object Result (DataRow Row)\r
1738                 {\r
1739                         object Result = null;\r
1740                         if (ResultType (Row) == typeof (DataColumn)) {\r
1741                                 \r
1742                                 if (!Row.Table.Columns.Contains (Element.ToString ()))\r
1743                                         throw new EvaluateException ("Column name '" + Element.ToString () + "' not found.");\r
1744                                 else\r
1745                                 {\r
1746                                         DataRowVersion rowVersion = DataRowVersion.Default;\r
1747                                         // if this row is deleted we get the original version, or else we get an exception.\r
1748                                         if (Row.RowState == DataRowState.Deleted)\r
1749                                                 rowVersion = DataRowVersion.Original;\r
1750                                         Result = Row [Element.ToString (), rowVersion];\r
1751                                 }\r
1752                         }\r
1753                         else\r
1754                                 Result = Element;\r
1755                                 \r
1756                         return Result;\r
1757                 }\r
1758                 \r
1759                 public override bool Test (DataRow Row)\r
1760                 {\r
1761                         throw new EvaluateException ();\r
1762                 }               \r
1763         }\r
1764 \r
1765         /// <summary>\r
1766         ///  Parent class of all the elements of expression\r
1767         /// </summary>\r
1768         internal abstract class ExpressionElement\r
1769         {               \r
1770                 // \r
1771                 // TODO/FIXME: This class should be inherited more than once. I mean own subclass for operators, functions,...\r
1772                 //\r
1773 \r
1774                 protected string exp1;\r
1775                 protected string exp2;\r
1776                 protected  Type _ResultType;\r
1777 \r
1778                 protected ArrayList Elements = new ArrayList ();\r
1779 \r
1780                 enum AGGREGATE {SUM, AVG, MIN, MAX, COUNT, STDEV, VAR}\r
1781                 //protected ArrayList Singles = new ArrayList ();\r
1782                 \r
1783                 /// <summary>\r
1784                 /// Tells does the current expressions match to current DataRow\r
1785                 /// </summary>\r
1786                 abstract public bool Test (DataRow Row);\r
1787 \r
1788                 public virtual object Result (DataRow Row) {return null;}\r
1789                 \r
1790                 public virtual Type ResultType (DataRow Row)\r
1791                 {\r
1792                         return _ResultType;\r
1793                 }\r
1794 \r
1795                 protected object CalculateResult (DataRow Row)\r
1796                 {\r
1797                         ExpressionElement E1 = ((ExpressionElement)Elements [0]);\r
1798                         ExpressionElement E2 = ((ExpressionElement)Elements [1]);\r
1799                         object Result = null;\r
1800                         object value1 = E1.Result (Row);\r
1801                         object value2 = E2.Result (Row);\r
1802                         Type t1 = value1.GetType ();\r
1803                         Type t2 = value2.GetType ();\r
1804                         \r
1805                                 // Check nulls\r
1806                         if (value1 ==  DBNull.Value && value2 == DBNull.Value)\r
1807                                 return null;\r
1808                         \r
1809                         // TODO: More types\r
1810                         \r
1811                         if (t1 == typeof (string) || t2 == typeof (string)) {\r
1812                                 \r
1813                                 if (t1 != typeof (string))\r
1814                                         value1 = Convert.ChangeType (value1, Type.GetTypeCode (t2));\r
1815                                 else if (t2 != typeof (string))\r
1816                                         value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));\r
1817                         }\r
1818                         \r
1819                         if (t1 != t2)\r
1820                                 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));\r
1821                         \r
1822                         Result = Calculate (value1, value2, t1);\r
1823                         \r
1824                         return Result; \r
1825                 }\r
1826                 protected virtual object Calculate (object value1, object value2, Type TempType)\r
1827                 {\r
1828                         return null;\r
1829                 }\r
1830                 \r
1831                 /// <summary>\r
1832                 ///  static method for comparing two ExpressionElement. This is used in =, <, >, <>, <=, >= elements.\r
1833                 ///  If elements are equal returns 0, if E1 is less that E2, return -1 else if E1 is greater 1 \r
1834                 /// </summary>\r
1835                 protected static int Compare (ExpressionElement E1, ExpressionElement E2, DataRow Row)\r
1836                 { \r
1837                         int ReturnValue = 0;\r
1838 \r
1839                         object value1 = E1.Result (Row);\r
1840                         object value2 = E2.Result (Row);\r
1841 \r
1842                         if ((value1 == null || value1 == DBNull.Value) && (value2 == null || value2 == DBNull.Value))\r
1843                                 return 0;\r
1844                         else if (value2 == null || value2 == DBNull.Value)\r
1845                                 return 1;\r
1846                         else if (value1 == null || value1 == DBNull.Value)\r
1847                                 return -1;\r
1848                         \r
1849                         Type t1 = value1.GetType ();\r
1850                         Type t2 = value2.GetType ();\r
1851                         \r
1852                         Type RT1 = E1.ResultType (Row);\r
1853                         Type RT2 = E2.ResultType (Row);\r
1854 \r
1855                         if (t1 == typeof (string) || t2 == typeof (string)) {\r
1856                                 // FIXME: If one of elements are string they both should be???\r
1857                                 //TempType = typeof (string);                           \r
1858                                 if (t1 != typeof (string))\r
1859                                         value1 = Convert.ChangeType (value1, Type.GetTypeCode (t2));\r
1860                                 else if (t2 != typeof (string))\r
1861                                         value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));\r
1862 \r
1863                                 \r
1864                                 if (!Row.Table.CaseSensitive) {\r
1865                                         value1 = ((string)value1).ToLower ();\r
1866                                         value2 = ((string)value2).ToLower ();\r
1867                                 }\r
1868                         }else if (t1 != t2) {\r
1869                                 \r
1870                                 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));\r
1871                         }\r
1872 \r
1873                         object Result = t1.InvokeMember ("CompareTo", BindingFlags.Default | \r
1874                                                                BindingFlags.InvokeMethod, null, \r
1875                                                                value1, \r
1876                                                                new object [] {value2});\r
1877                         ReturnValue = (int)Result;\r
1878 \r
1879                         return ReturnValue;\r
1880                 }\r
1881 \r
1882                 /// <summary>\r
1883                 ///  Finds and creates Expression elements.\r
1884                 ///  This presumes that expression is valid.\r
1885                 /// </summary>\r
1886                 protected void ParseExpression (string s)\r
1887                 {       \r
1888                         //\r
1889                         // TODO/FIXME: IMHO, this should be done with different kind of parsing:\r
1890                         // char by char not operand by operand. \r
1891                         //\r
1892 \r
1893                         string inside = ""; // stores string betwee parentheses like a = 12 and (b = 1 or b = 2)\r
1894                         string function = ""; // stores fuction paramters like substring (this, are, paramters)\r
1895                         string s1 = "";\r
1896                         string s2 = "";\r
1897                         int temp = -1;\r
1898                         \r
1899                         // Find parenthesis\r
1900                         if ((temp = s.IndexOf ("(")) != -1) {\r
1901                                 \r
1902                                 string functionName = "";\r
1903                                 while (temp != 0 && s [temp - 1] != '=')\r
1904                                         temp--;\r
1905 \r
1906                                 // Get the previous element of expression\r
1907                                 while (s [temp] != '(') {\r
1908                                         char c = s [temp];\r
1909                                         functionName = functionName + c;\r
1910                                         temp++;\r
1911                                 }\r
1912 \r
1913                                 functionName = functionName.Trim ();\r
1914                                 functionName = functionName.ToLower ();\r
1915 \r
1916                                 // check if previous element is a function\r
1917                                 if (!functionName.EndsWith ("convert") && !functionName.EndsWith ("len") &&\r
1918                                     !functionName.EndsWith ("isnull") && !functionName.EndsWith ("iif") &&\r
1919                                     !functionName.EndsWith ("trim") && !functionName.EndsWith ("substring") &&\r
1920                                     !functionName.EndsWith ("sum") && !functionName.EndsWith ("avg") &&\r
1921                                     !functionName.EndsWith ("min") && !functionName.EndsWith ("max") &&\r
1922                                     !functionName.EndsWith ("count") && !functionName.EndsWith ("stdev") &&\r
1923                                     !functionName.EndsWith ("var")&& !functionName.EndsWith ("in")) {\r
1924                                         \r
1925                                         int startIndex = s.IndexOf ("(");\r
1926                                         int i = startIndex + 1;\r
1927                                         int par = 1;\r
1928                                         char c;                         \r
1929                                         while (par > 0) {\r
1930 \r
1931                                                 c = s [i];\r
1932                                                 if (c == '(')\r
1933                                                         par++;\r
1934                                                 if (c == ')')\r
1935                                                         par--;\r
1936                                                 \r
1937                                                 if (par > 0)\r
1938                                                         inside += c;\r
1939                                                 i++;\r
1940                                         }\r
1941                                         \r
1942                                         s = s.Remove (startIndex, i - startIndex);\r
1943                                 }               \r
1944                                              \r
1945                         }\r
1946                         \r
1947                         string string1 = null;\r
1948                         string string2 = null;\r
1949                         if (FindOrElement (s, ref string1, ref string2))                \r
1950                                 CreateOrElement (string1, string2, inside);\r
1951 \r
1952                         else if (FindAndElement (s, ref string1, ref string2))\r
1953                                 CreateAndElement (string1, string2, inside);\r
1954 \r
1955                         // find LIKE\r
1956                         else if (FindLikeElement (s, ref string1, ref string2))\r
1957                                 CreateLikeElement (string1, string2, inside);\r
1958                         \r
1959                         // find IN\r
1960                         else if (FindInElement (s, ref string1, ref string2))\r
1961                                 CreateInElement (string1, string2, inside);\r
1962 \r
1963                         // find =\r
1964                         else if (FindEqualElement (s, ref string1, ref string2))\r
1965                                 CreateEqualsElement (string1, string2, inside);\r
1966 \r
1967                         // find <>\r
1968                         else if (FindUnequalElement (s, ref string1, ref string2))\r
1969                                 CreateUnequalsElement (string1, string2, inside);\r
1970 \r
1971                         // find <=\r
1972                         else if (FindLessThanOrEqualElement (s, ref string1, ref string2))\r
1973                                 CreateLessThanOrEqualElement (string1, string2, inside);\r
1974 \r
1975                         // find <\r
1976                         else if (FindLessThanElement (s, ref string1, ref string2))\r
1977                                 CreateLessThanElement (string1, string2, inside);\r
1978 \r
1979                         // find >=\r
1980                         else if (FindGreaterThanOrEqualElement (s, ref string1, ref string2))\r
1981                                 CreateGreaterThanOrEqualElement (string1, string2, inside);\r
1982 \r
1983                         // find >\r
1984                         else if (FindGreaterThanElement (s, ref string1, ref string2))\r
1985                                 CreateGreaterThanElement (string1, string2,  inside);\r
1986 \r
1987                         // if there wasn't any operators like 'and' or 'not' there still could be\r
1988                         // arithmetic operators like '+' or '-' or functions like 'iif' or 'substring'\r
1989 \r
1990                         // find *\r
1991                         else if (FindMultiplyElement (s, ref string1, ref string2))\r
1992                                 CreateMultiplyElement (string1, string2, inside);\r
1993                         \r
1994                         // find /\r
1995                         else if (FindDivideElement (s, ref string1, ref string2))\r
1996                                 CreateDivideElement (string1, string2, inside);\r
1997 \r
1998 \r
1999                         // find +\r
2000                         else if (FindAdditionElement (s, ref string1, ref string2))\r
2001                                  CreateAdditionElement (string1, string2, inside);\r
2002 \r
2003                         // find -\r
2004                         else if (FindSubtractElement (s, ref string1, ref string2))\r
2005                                 CreateSubtractionElement (string1, string2, inside);\r
2006 \r
2007                         // find %\r
2008                         else if (FindModulusElement (s, ref string1, ref string2))\r
2009                                 CreateModulusElement (string1, string2, inside);\r
2010 \r
2011                         // find sum ()\r
2012                         else if (FindAggregateElement (s, AGGREGATE.SUM))\r
2013                                 Elements.Add (new ExpressionSum (s.Trim ()));\r
2014 \r
2015                         // find avg ()\r
2016                         else if (FindAggregateElement (s, AGGREGATE.AVG))\r
2017                                 Elements.Add (new ExpressionAvg (s.Trim ()));\r
2018 \r
2019                         // find min ()\r
2020                         else if (FindAggregateElement (s, AGGREGATE.MIN))\r
2021                                 Elements.Add (new ExpressionMin (s.Trim ()));\r
2022 \r
2023                         // find max ()\r
2024                         else if (FindAggregateElement (s, AGGREGATE.MAX))\r
2025                                 Elements.Add (new ExpressionMax (s.Trim ()));\r
2026 \r
2027                         // find count ()\r
2028                         else if (FindAggregateElement (s, AGGREGATE.COUNT))\r
2029                                 Elements.Add (new ExpressionCount (s.Trim ()));                            \r
2030 \r
2031                         // find stdev ()\r
2032                         else if (FindAggregateElement (s, AGGREGATE.STDEV))\r
2033                                 Elements.Add (new ExpressionStdev (s.Trim ()));\r
2034 \r
2035                         // find var ()\r
2036                         else if (FindAggregateElement (s, AGGREGATE.VAR))\r
2037                                 Elements.Add (new ExpressionVar (s.Trim ()));\r
2038 \r
2039                         // find len\r
2040                         else if (FindLenElement (s))\r
2041                                 Elements.Add (new ExpressionLen (s.Trim ()));\r
2042 \r
2043                         // find iif\r
2044                         else if (FindIifElement (s))\r
2045                                 Elements.Add (new ExpressionIif (s.Trim ()));\r
2046 \r
2047                         // find isnull\r
2048                         else if (FindIsNullElement (s))\r
2049                                 Elements.Add (new ExpressionIsNull (s.Trim ()));\r
2050 \r
2051                         // find substring\r
2052                         else if (FindSubstringElement (s))\r
2053                                 Elements.Add (new ExpressionSubstring (s.Trim ()));\r
2054 \r
2055                         // if expression is like '(something someoperator something)'\r
2056                         else if (inside.Trim () != string.Empty)\r
2057                                 ParseExpression (inside);\r
2058 \r
2059                         // At least, if it wasnt any of the above it is just normat string or int\r
2060                         // or....                       \r
2061                         else\r
2062                                 Elements.Add (new ExpressionSingleElement (s.Trim ()));                 \r
2063                 }\r
2064 \r
2065                 #region CheckElement methods\r
2066 \r
2067                 //\r
2068                 // These methods are temporary for now\r
2069                 //\r
2070 \r
2071                 private bool FindOrElement (string s, ref string s1, ref string s2)\r
2072                 {\r
2073                         string stemp = s.ToLower ();\r
2074                         int indexOf = stemp.IndexOf("or");\r
2075 \r
2076                         if (indexOf == -1)\r
2077                                 return false;\r
2078 \r
2079                         // Test if or is between ''\r
2080                         int oldIndex = -1;                      \r
2081                         while ((indexOf = stemp.IndexOf ("or", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2082                                 \r
2083                                 oldIndex = indexOf;\r
2084 \r
2085                                 // check is the 'or' element part of string element\r
2086                                 if (IsPartOfStringElement (stemp, indexOf))\r
2087                                         continue;\r
2088                                 \r
2089                                 // Check is or part of something else for example column name\r
2090                                 if (indexOf != 0) {\r
2091                                         \r
2092                                         if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')\r
2093                                                 continue;\r
2094                                 }\r
2095                                 \r
2096                                 if (indexOf < s.Length + 2) {\r
2097                                         \r
2098                                         if (stemp [indexOf + 2] != ' ' && stemp [indexOf + 2] != '\'')\r
2099                                                 continue;\r
2100                                 }\r
2101 \r
2102                                 if (IsPartOfFunction (stemp, indexOf))\r
2103                                         continue;\r
2104 \r
2105                                 s1 = s.Substring (0, indexOf).Trim ();\r
2106                                 s2 = s.Substring (indexOf + 2).Trim ();\r
2107 \r
2108                                 return true;\r
2109                         }\r
2110 \r
2111                         return false;\r
2112                 }\r
2113                 \r
2114                 private bool FindAndElement (string s, ref string s1, ref string s2)\r
2115                 {\r
2116                         string stemp = s.ToLower ();\r
2117                         int indexOf = stemp.IndexOf("and");\r
2118 \r
2119                         if (indexOf == -1)\r
2120                                 return false;\r
2121 \r
2122                         // Test if or is between ''\r
2123                         int oldIndex = -1;\r
2124                         while ((indexOf = stemp.IndexOf ("and", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2125                                 \r
2126                                 oldIndex = indexOf;\r
2127                                 \r
2128                                 // check is the 'and' element part of string element\r
2129                                 if (IsPartOfStringElement (stemp, indexOf))\r
2130                                         continue;\r
2131 \r
2132 \r
2133                                 // Check is or part of something else for example column name\r
2134                                 if (indexOf != 0) {\r
2135                                         \r
2136                                         if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')\r
2137                                                 continue;\r
2138                                 }\r
2139                                 \r
2140                                 if (indexOf < stemp.Length + 3) {\r
2141                                         \r
2142                                         if (stemp [indexOf + 3] != ' ' && stemp [indexOf + 3] != '\'')\r
2143                                                 continue;\r
2144                                 }\r
2145 \r
2146                                 if (IsPartOfFunction (stemp, indexOf))\r
2147                                         continue;\r
2148 \r
2149 \r
2150                                 s1 = s.Substring (0, indexOf).Trim ();\r
2151                                 s2 = s.Substring (indexOf + 3).Trim ();\r
2152                                 return true;\r
2153                         }\r
2154 \r
2155                         return false;\r
2156                 }\r
2157 \r
2158                 private bool FindLikeElement (string s, ref string s1, ref string s2)\r
2159                 {\r
2160                         string stemp = s.ToLower ();\r
2161                         int indexOf = stemp.IndexOf("like");\r
2162 \r
2163                         if (indexOf == -1)\r
2164                                 return false;\r
2165 \r
2166                         // Test if or is between ''\r
2167                         int oldIndex = -1;\r
2168                         while ((indexOf = stemp.IndexOf ("like", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2169                                 \r
2170                                 oldIndex = indexOf;\r
2171                                 \r
2172                                 // check is the 'and' element part of string element\r
2173                                 if (IsPartOfStringElement (stemp, indexOf))\r
2174                                         continue;\r
2175 \r
2176 \r
2177                                 // Check is or part of something else for example column name\r
2178                                 if (indexOf != 0) {\r
2179                                         \r
2180                                         if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')\r
2181                                                 continue;\r
2182                                 }\r
2183                                 \r
2184                                 if (indexOf < stemp.Length + 4) {\r
2185                                         \r
2186                                         if (stemp [indexOf + 4] != ' ' && stemp [indexOf + 4] != '\'')\r
2187                                                 continue;\r
2188                                 }\r
2189 \r
2190                                 if (IsPartOfFunction (stemp, indexOf))\r
2191                                         continue;\r
2192 \r
2193 \r
2194                                 s1 = s.Substring (0, indexOf).Trim ();\r
2195                                 s2 = s.Substring (indexOf + 4).Trim ();\r
2196                                 return true;\r
2197                         }\r
2198 \r
2199                         return false;\r
2200                 }\r
2201 \r
2202                 private bool FindEqualElement (string s, ref string s1, ref string s2)\r
2203                 {\r
2204                         string stemp = s.ToLower ();\r
2205                         int indexOf = stemp.IndexOf ("=");\r
2206 \r
2207                         if (indexOf == -1)\r
2208                                 return false;\r
2209                         \r
2210                         int oldIndex = -1;\r
2211 \r
2212                         while ((indexOf = stemp.IndexOf ("=", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2213 \r
2214                                 oldIndex = indexOf;\r
2215 \r
2216                                 // Check is the = part of <= or >=\r
2217                                 if (stemp [indexOf - 1] == '<' || stemp [indexOf - 1] == '>')\r
2218                                         continue;\r
2219 \r
2220                                 // Check is the = element part of string element\r
2221                                 if (IsPartOfStringElement (stemp, indexOf))\r
2222                                         continue;\r
2223 \r
2224                                 // Check is or part of column name\r
2225                                 if (IsPartOfColumnName (stemp, indexOf))\r
2226                                         continue;\r
2227                                         \r
2228                                 if (IsPartOfFunction (stemp, indexOf))\r
2229                                         continue;\r
2230 \r
2231                                 s1 = s.Substring (0, indexOf).Trim ();\r
2232                                 s2 = s.Substring (indexOf + 1).Trim ();\r
2233                                 \r
2234                                 return true;\r
2235                         }\r
2236 \r
2237                         return false;\r
2238                 }\r
2239 \r
2240                 private bool FindUnequalElement (string s, ref string s1, ref string s2)\r
2241                 {\r
2242                         string stemp = s.ToLower ();\r
2243                         int indexOf = stemp.IndexOf ("<>");\r
2244 \r
2245                         if (stemp.IndexOf ("<>") == -1)\r
2246                                 return false;\r
2247                        \r
2248                         int oldIndex = -1;\r
2249                         while ((indexOf = stemp.IndexOf ("<>", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2250 \r
2251                                 oldIndex = indexOf;\r
2252 \r
2253                                 // test if next charachter is something else than ' '\r
2254                                 bool failed = false;\r
2255 \r
2256                                 // Check is the <> element part of string element\r
2257                                 if (IsPartOfStringElement (stemp, indexOf))\r
2258                                         continue;\r
2259 \r
2260                                 // Check is or part of column name\r
2261                                 if (IsPartOfColumnName (stemp, indexOf))\r
2262                                         continue;\r
2263                                         \r
2264                                 if (IsPartOfFunction (stemp, indexOf))\r
2265                                         continue;\r
2266 \r
2267                                 s1 = s.Substring (0, indexOf).Trim ();\r
2268                                 s2 = s.Substring (indexOf + 2).Trim ();\r
2269                                 \r
2270                                 return true;\r
2271                         }\r
2272 \r
2273                         return false;\r
2274                         \r
2275                 }\r
2276 \r
2277 \r
2278                 private bool FindLessThanElement (string s, ref string s1, ref string s2)\r
2279                 {\r
2280                         string stemp = s.ToLower ();\r
2281                         int indexOf = stemp.IndexOf ("<");\r
2282 \r
2283                         if (indexOf == -1)\r
2284                                 return false;\r
2285 \r
2286                         int oldIndex = -1;\r
2287                         while ((indexOf = stemp.IndexOf ("<", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2288 \r
2289                                 oldIndex = indexOf;\r
2290 \r
2291                                 // if < is part of <> or <=\r
2292                                 if (stemp [indexOf + 1] == '>' || stemp [indexOf + 1] == '=')\r
2293                                         continue;\r
2294 \r
2295                                 // Test is < element part of string element\r
2296                                 if (IsPartOfStringElement (stemp, indexOf))\r
2297                                         continue;\r
2298 \r
2299                                 // Check is or part of column name\r
2300                                 if (IsPartOfColumnName (stemp, indexOf))\r
2301                                         continue;\r
2302 \r
2303                                 if (IsPartOfFunction (stemp, indexOf))\r
2304                                         continue;\r
2305 \r
2306                                 s1 = s.Substring (0, indexOf).Trim ();\r
2307                                 s2 = s.Substring (indexOf + 1).Trim ();\r
2308 \r
2309                                 return true;\r
2310                         }\r
2311                 \r
2312                         return false;                   \r
2313                 }\r
2314 \r
2315                 private bool FindLessThanOrEqualElement (string s, ref string s1, ref string s2)\r
2316                 {\r
2317                         string stemp = s.ToLower ();\r
2318                         int indexOf = stemp.IndexOf ("<=");\r
2319 \r
2320                         if (indexOf == -1)\r
2321                                 return false;\r
2322 \r
2323                         int oldIndex = -1;\r
2324                         while ((indexOf = stemp.IndexOf ("<=", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2325 \r
2326                                 oldIndex = indexOf;\r
2327                                 // Test is <= element part of string element\r
2328                                 if (IsPartOfStringElement (stemp, indexOf))\r
2329                                         continue;\r
2330 \r
2331                                 // Check is or part of column name\r
2332                                 if (IsPartOfColumnName (stemp, indexOf))\r
2333                                         continue;\r
2334 \r
2335                                 if (IsPartOfFunction (stemp, indexOf))\r
2336                                         continue;\r
2337 \r
2338                                 s1 = s.Substring (0, indexOf).Trim ();\r
2339                                 s2 = s.Substring (indexOf + 2).Trim ();\r
2340 \r
2341                                 return true;\r
2342                         }\r
2343                 \r
2344                         return false;                   \r
2345                 }\r
2346 \r
2347                 private bool FindGreaterThanElement (string s, ref string s1, ref string s2)\r
2348                 {\r
2349                         string stemp = s.ToLower ();\r
2350                         int indexOf = stemp.IndexOf (">");\r
2351 \r
2352                         if (indexOf == -1)\r
2353                                 return false;\r
2354 \r
2355                         int oldIndex = -1;\r
2356                         while ((indexOf = stemp.IndexOf (">", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2357 \r
2358                                 oldIndex = indexOf;\r
2359 \r
2360                                 // if < is part of <> or <=\r
2361                                 if (stemp [indexOf - 1] == '<' || stemp [indexOf + 1] == '=')\r
2362                                         continue;\r
2363 \r
2364                                 // Test is < element part of string element\r
2365                                 if (IsPartOfStringElement (stemp, indexOf))\r
2366                                         continue;\r
2367 \r
2368                                 // Check is or part of column name\r
2369                                 if (IsPartOfColumnName (stemp, indexOf))\r
2370                                         continue;\r
2371 \r
2372                                 if (IsPartOfFunction (stemp, indexOf))\r
2373                                         continue;\r
2374 \r
2375                                 s1 = s.Substring (0, indexOf).Trim ();\r
2376                                 s2 = s.Substring (indexOf + 1).Trim ();\r
2377                                 return true;\r
2378                         }\r
2379                 \r
2380                         return false;                   \r
2381                 }\r
2382 \r
2383                 private bool FindGreaterThanOrEqualElement (string s, ref string s1, ref string s2)\r
2384                 {\r
2385                         string stemp = s.ToLower ();\r
2386                         int indexOf = stemp.IndexOf (">=");\r
2387 \r
2388                         if (indexOf == -1)\r
2389                                 return false;\r
2390 \r
2391                         int oldIndex = -1;\r
2392                         while ((indexOf = stemp.IndexOf (">=", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2393 \r
2394                                 oldIndex = indexOf;\r
2395                                 bool failed = false;\r
2396                                 // Test is <= element part of string element\r
2397 \r
2398                                 // Check is or part of column name\r
2399                                 if (IsPartOfColumnName (stemp, indexOf))\r
2400                                         continue;\r
2401 \r
2402                                 // is the element part of string element\r
2403                                 if (IsPartOfStringElement (stemp, indexOf))\r
2404                                         continue;\r
2405 \r
2406                                 if (IsPartOfFunction (stemp, indexOf))\r
2407                                         continue;\r
2408 \r
2409                                 s1 = s.Substring (0, indexOf).Trim ();\r
2410                                 s2 = s.Substring (indexOf + 2).Trim ();\r
2411 \r
2412                                 return true;\r
2413                         }\r
2414                 \r
2415                         return false;                   \r
2416                 }\r
2417 \r
2418                 private bool FindAdditionElement (string s, ref string s1, ref string s2)\r
2419                 {\r
2420                         string stemp = s.ToLower ();\r
2421                         int indexOf = stemp.IndexOf ("+");\r
2422 \r
2423                         if (indexOf == -1)\r
2424                                 return false;\r
2425 \r
2426                         int oldIndex = -1;\r
2427                         while ((indexOf = stemp.IndexOf ("+", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2428 \r
2429                                 // FIXME: if '+' represents sign of integer\r
2430 \r
2431                                 oldIndex = indexOf;\r
2432                                 bool failed = false;\r
2433 \r
2434                                 // Check is or part of column name\r
2435                                 if (IsPartOfColumnName (stemp, indexOf))\r
2436                                         continue;\r
2437 \r
2438                                 // is the element part of string element\r
2439                                 if (IsPartOfStringElement (stemp, indexOf))\r
2440                                         continue;\r
2441 \r
2442                                 if (IsPartOfFunction (stemp, indexOf))\r
2443                                         continue;\r
2444 \r
2445                                 s1 = s.Substring (0, indexOf).Trim ();\r
2446                                 s2 = s.Substring (indexOf + 1).Trim ();\r
2447 \r
2448                                 return true;\r
2449                         }\r
2450                 \r
2451                         return false;                   \r
2452                 }\r
2453 \r
2454                 private bool FindSubtractElement (string s, ref string s1, ref string s2)\r
2455                 {\r
2456                         string stemp = s.ToLower ();\r
2457                         int indexOf = stemp.IndexOf ("-");\r
2458 \r
2459                         if (indexOf == -1)\r
2460                                 return false;\r
2461 \r
2462                         int oldIndex = -1;\r
2463                         while ((indexOf = stemp.IndexOf ("-", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2464 \r
2465                                 oldIndex = indexOf;\r
2466                                 bool failed = false;\r
2467 \r
2468                                 // check is this lonely element         \r
2469                                 failed = true;\r
2470                                 for (int i = indexOf - 1; i >= 0; i--) {\r
2471                                         if (stemp [i] != ' ') {\r
2472                                                 failed = false;\r
2473                                                 break;\r
2474                                         }\r
2475                                 }\r
2476                                         \r
2477                                 if (failed)\r
2478                                         continue;\r
2479 \r
2480                                 // Check is or part of column name\r
2481                                 if (IsPartOfColumnName (stemp, indexOf))\r
2482                                         continue;\r
2483 \r
2484                                 // is the element part of string element\r
2485                                 if (IsPartOfStringElement (stemp, indexOf))\r
2486                                         continue;\r
2487 \r
2488                                 if (IsPartOfFunction (stemp, indexOf))\r
2489                                         continue;\r
2490 \r
2491                                 s1 = s.Substring (0, indexOf).Trim ();\r
2492                                 s2 = s.Substring (indexOf + 1).Trim ();\r
2493 \r
2494                                 return true;\r
2495                         }\r
2496                 \r
2497                         return false;                   \r
2498                 }\r
2499 \r
2500                 private bool FindMultiplyElement (string s, ref string s1, ref string s2)\r
2501                 {\r
2502                         string stemp = s.ToLower ();\r
2503                         int indexOf = stemp.IndexOf ("*");\r
2504 \r
2505                         if (indexOf == -1)\r
2506                                 return false;\r
2507 \r
2508                         int oldIndex = -1;\r
2509                         while ((indexOf = stemp.IndexOf ("*", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2510 \r
2511 \r
2512                                 oldIndex = indexOf;\r
2513                                 bool failed = false;\r
2514 \r
2515                                 // FIXME: If there is a divide operator before multiply operator.\r
2516 \r
2517                                 // Check is or part of column name\r
2518                                 if (IsPartOfColumnName (stemp, indexOf))\r
2519                                         continue;\r
2520 \r
2521                                 // is the element part of string element\r
2522                                 if (IsPartOfStringElement (stemp, indexOf))\r
2523                                         continue;\r
2524 \r
2525                                 if (IsPartOfFunction (stemp, indexOf))\r
2526                                         continue;\r
2527 \r
2528                                 s1 = s.Substring (0, indexOf).Trim ();\r
2529                                 s2 = s.Substring (indexOf + 1).Trim ();\r
2530 \r
2531                                 return true;\r
2532                         }\r
2533                 \r
2534                         return false;                   \r
2535                 }\r
2536 \r
2537                 private bool FindDivideElement (string s, ref string s1, ref string s2)\r
2538                 {\r
2539                         string stemp = s.ToLower ();\r
2540                         int indexOf = stemp.IndexOf ("/");\r
2541 \r
2542                         if (indexOf == -1)\r
2543                                 return false;\r
2544 \r
2545                         int oldIndex = -1;\r
2546                         while ((indexOf = stemp.IndexOf ("/", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2547 \r
2548 \r
2549                                 oldIndex = indexOf;\r
2550                                 bool failed = false;\r
2551 \r
2552                                 // FIXME: If there is a multiply operator before divide operator.\r
2553 \r
2554                                 // Check is or part of column name\r
2555                                 if (IsPartOfColumnName (stemp, indexOf))\r
2556                                         continue;\r
2557 \r
2558                                 // is the element part of string element\r
2559                                 if (IsPartOfStringElement (stemp, indexOf))\r
2560                                         continue;\r
2561 \r
2562                                 if (IsPartOfFunction (stemp, indexOf))\r
2563                                         continue;\r
2564                                     \r
2565                                 s1 = s.Substring (0, indexOf).Trim ();\r
2566                                 s2 = s.Substring (indexOf + 1).Trim ();\r
2567 \r
2568                                 return true;\r
2569                         }\r
2570                 \r
2571                         return false;                   \r
2572                 }\r
2573 \r
2574                 private bool FindModulusElement (string s, ref string s1, ref string s2)\r
2575                 {\r
2576                         string stemp = s.ToLower ();\r
2577                         int indexOf = stemp.IndexOf ("%");\r
2578 \r
2579                         if (indexOf == -1)\r
2580                                 return false;\r
2581 \r
2582                         int oldIndex = -1;\r
2583                         while ((indexOf = stemp.IndexOf ("%", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2584 \r
2585 \r
2586                                 oldIndex = indexOf;\r
2587                                 bool failed = false;\r
2588 \r
2589                                 // FIXME: If there is a multiply operator before divide operator.\r
2590 \r
2591                                 // Check is or part of column name\r
2592                                 if (IsPartOfColumnName (stemp, indexOf))\r
2593                                         continue;\r
2594 \r
2595                                 // is the element part of string element\r
2596                                 if (IsPartOfStringElement (stemp, indexOf))\r
2597                                         continue;\r
2598 \r
2599                                 s1 = s.Substring (0, indexOf).Trim ();\r
2600                                 s2 = s.Substring (indexOf + 1).Trim ();\r
2601 \r
2602                                 return true;\r
2603                         }\r
2604                 \r
2605                         return false;                   \r
2606                 }\r
2607 \r
2608                 private bool FindAggregateElement (string s, AGGREGATE aggregate)\r
2609                 {\r
2610                         string agg = null;\r
2611 \r
2612                         switch (aggregate) {\r
2613 \r
2614                                 case AGGREGATE.SUM:\r
2615                                         agg = "sum";\r
2616                                         break;\r
2617                                 case AGGREGATE.AVG:\r
2618                                         agg = "avg";\r
2619                                         break;\r
2620                                 case AGGREGATE.MIN:\r
2621                                         agg = "min";\r
2622                                         break;\r
2623                                 case AGGREGATE.MAX:\r
2624                                         agg = "max";\r
2625                                         break;\r
2626                                 case AGGREGATE.COUNT:\r
2627                                         agg = "count";\r
2628                                         break;\r
2629                                 case AGGREGATE.STDEV:\r
2630                                         agg = "stdev";\r
2631                                         break;\r
2632                                 case AGGREGATE.VAR:\r
2633                                         agg = "var";\r
2634                                         break;\r
2635                                 default:\r
2636                                         throw new NotImplementedException ();\r
2637                         }\r
2638                                \r
2639                                 \r
2640                         string stemp = s.ToLower ();\r
2641                         int indexOf = stemp.IndexOf (agg);\r
2642 \r
2643                         if (indexOf == -1)\r
2644                                 return false;\r
2645 \r
2646                         int oldIndex = -1;\r
2647                         while ((indexOf = stemp.IndexOf (agg, oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2648 \r
2649                                 oldIndex = indexOf;\r
2650                                 bool failed = false;\r
2651 \r
2652                                 // Check is or part of column name\r
2653                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2654                                         continue;\r
2655 \r
2656                                 // is the element part of string element\r
2657                                 if (IsPartOfStringElement (stemp, indexOf))\r
2658                                         continue;\r
2659 \r
2660 \r
2661                                 return true;\r
2662                         }\r
2663                 \r
2664                         return false;                   \r
2665 \r
2666                 }\r
2667                 \r
2668                 private bool FindSumElement (string s)\r
2669                 {\r
2670                         string stemp = s.ToLower ();\r
2671                         int indexOf = stemp.IndexOf ("sum");\r
2672 \r
2673                         if (indexOf == -1)\r
2674                                 return false;\r
2675 \r
2676                         int oldIndex = -1;\r
2677                         while ((indexOf = stemp.IndexOf ("sum", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2678 \r
2679                                 oldIndex = indexOf;\r
2680                                 bool failed = false;\r
2681 \r
2682                                 // Check is or part of column name\r
2683                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2684                                         continue;\r
2685 \r
2686                                 // is the element part of string element\r
2687                                 if (IsPartOfStringElement (stemp, indexOf))\r
2688                                         continue;\r
2689 \r
2690 \r
2691                                 return true;\r
2692                         }\r
2693                 \r
2694                         return false;                   \r
2695                 }\r
2696 \r
2697                 private bool FindAvgElement (string s)\r
2698                 {\r
2699                         string stemp = s.ToLower ();\r
2700                         int indexOf = stemp.IndexOf ("avg");\r
2701 \r
2702                         if (indexOf == -1)\r
2703                                 return false;\r
2704 \r
2705                         int oldIndex = -1;\r
2706                         while ((indexOf = stemp.IndexOf ("avg", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2707 \r
2708                                 oldIndex = indexOf;\r
2709                                 bool failed = false;\r
2710 \r
2711                                 // Check is or part of column name\r
2712                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2713                                         continue;\r
2714 \r
2715                                 // is the element part of string element\r
2716                                 if (IsPartOfStringElement (stemp, indexOf))\r
2717                                         continue;\r
2718 \r
2719                                 return true;\r
2720                         }\r
2721                 \r
2722                         return false;                   \r
2723                 }\r
2724 \r
2725                 private bool FindMinElement (string s)\r
2726                 {\r
2727                         string stemp = s.ToLower ();\r
2728                         int indexOf = stemp.IndexOf ("min");\r
2729 \r
2730                         if (indexOf == -1)\r
2731                                 return false;\r
2732 \r
2733                         int oldIndex = -1;\r
2734                         while ((indexOf = stemp.IndexOf ("min", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2735 \r
2736                                 oldIndex = indexOf;\r
2737                                 bool failed = false;\r
2738 \r
2739                                 // Check is or part of column name\r
2740                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2741                                         continue;\r
2742 \r
2743                                 // is the element part of string element\r
2744                                 if (IsPartOfStringElement (stemp, indexOf))\r
2745                                         continue;\r
2746 \r
2747                                 return true;\r
2748                         }\r
2749                 \r
2750                         return false;                   \r
2751                 }\r
2752 \r
2753                 private bool FindMaxElement (string s)\r
2754                 {\r
2755                         string stemp = s.ToLower ();\r
2756                         int indexOf = stemp.IndexOf ("max");\r
2757 \r
2758                         if (indexOf == -1)\r
2759                                 return false;\r
2760 \r
2761                         int oldIndex = -1;\r
2762                         while ((indexOf = stemp.IndexOf ("max", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2763 \r
2764                                 oldIndex = indexOf;\r
2765                                 bool failed = false;\r
2766 \r
2767                                 // Check is or part of column name\r
2768                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2769                                         continue;\r
2770 \r
2771                                 // is the element part of string element\r
2772                                 if (IsPartOfStringElement (stemp, indexOf))\r
2773                                         continue;\r
2774 \r
2775                                 return true;\r
2776                         }\r
2777                 \r
2778                         return false;                   \r
2779                 }\r
2780 \r
2781                 private bool FindCountElement (string s)\r
2782                 {\r
2783                         string stemp = s.ToLower ();\r
2784                         int indexOf = stemp.IndexOf ("count");\r
2785 \r
2786                         if (indexOf == -1)\r
2787                                 return false;\r
2788 \r
2789                         int oldIndex = -1;\r
2790                         while ((indexOf = stemp.IndexOf ("count", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2791 \r
2792                                 oldIndex = indexOf;\r
2793                                 bool failed = false;\r
2794 \r
2795                                 // Check is or part of column name\r
2796                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2797                                         continue;\r
2798 \r
2799                                 // is the element part of string element\r
2800                                 if (IsPartOfStringElement (stemp, indexOf))\r
2801                                         continue;\r
2802 \r
2803                                 return true;\r
2804                         }\r
2805                 \r
2806                         return false;                   \r
2807                 }\r
2808 \r
2809                 private bool FindStdevElement (string s)\r
2810                 {\r
2811                         string stemp = s.ToLower ();\r
2812                         int indexOf = stemp.IndexOf ("stdev");\r
2813 \r
2814                         if (indexOf == -1)\r
2815                                 return false;\r
2816 \r
2817                         int oldIndex = -1;\r
2818                         while ((indexOf = stemp.IndexOf ("stdev", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2819 \r
2820                                 oldIndex = indexOf;\r
2821                                 bool failed = false;\r
2822 \r
2823                                 // Check is or part of column name\r
2824                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2825                                         continue;\r
2826 \r
2827                                 // is the element part of string element\r
2828                                 if (IsPartOfStringElement (stemp, indexOf))\r
2829                                         continue;\r
2830 \r
2831                                 return true;\r
2832                         }\r
2833                 \r
2834                         return false;                   \r
2835                 }\r
2836 \r
2837                 private bool FindVarElement (string s)\r
2838                 {\r
2839                         string stemp = s.ToLower ();\r
2840                         int indexOf = stemp.IndexOf ("var");\r
2841 \r
2842                         if (indexOf == -1)\r
2843                                 return false;\r
2844 \r
2845                         int oldIndex = -1;\r
2846                         while ((indexOf = stemp.IndexOf ("var", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2847 \r
2848                                 oldIndex = indexOf;\r
2849                                 bool failed = false;\r
2850 \r
2851                                 // Check is or part of column name\r
2852                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2853                                         continue;\r
2854 \r
2855                                 // is the element part of string element\r
2856                                 if (IsPartOfStringElement (stemp, indexOf))\r
2857                                         continue;\r
2858 \r
2859                                 return true;\r
2860                         }\r
2861                 \r
2862                         return false;                   \r
2863                 }\r
2864 \r
2865                 private bool FindLenElement (string s)\r
2866                 {\r
2867                         string stemp = s.ToLower ();\r
2868                         int indexOf = stemp.IndexOf ("len");\r
2869 \r
2870                         if (indexOf == -1)\r
2871                                 return false;\r
2872 \r
2873                         int oldIndex = -1;\r
2874                         while ((indexOf = stemp.IndexOf ("len", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2875 \r
2876                                 oldIndex = indexOf;\r
2877                                 bool failed = false;\r
2878 \r
2879                                 // Check is or part of column name\r
2880                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2881                                         continue;\r
2882 \r
2883                                 // is the element part of string element\r
2884                                 if (IsPartOfStringElement (stemp, indexOf))\r
2885                                         continue;\r
2886 \r
2887 \r
2888                                 return true;\r
2889                         }\r
2890                 \r
2891                         return false;                   \r
2892                 }\r
2893 \r
2894                 private bool FindIifElement (string s)\r
2895                 {\r
2896                         string stemp = s.ToLower ();\r
2897                         int indexOf = stemp.IndexOf ("iif");\r
2898 \r
2899                         if (indexOf == -1)\r
2900                                 return false;\r
2901 \r
2902                         int oldIndex = -1;\r
2903                         while ((indexOf = stemp.IndexOf ("iif", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2904 \r
2905                                 oldIndex = indexOf;\r
2906                                 bool failed = false;\r
2907 \r
2908                                 // Check is or part of column name\r
2909                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2910                                         continue;\r
2911 \r
2912                                 // is the element part of string element\r
2913                                 if (IsPartOfStringElement (stemp, indexOf))\r
2914                                         continue;\r
2915 \r
2916                                 return true;\r
2917                         }\r
2918                 \r
2919                         return false;                   \r
2920                 }\r
2921 \r
2922                 private bool FindIsNullElement (string s)\r
2923                 {\r
2924                         string stemp = s.ToLower ();\r
2925                         int indexOf = stemp.IndexOf ("isnull");\r
2926 \r
2927                         if (indexOf == -1)\r
2928                                 return false;\r
2929 \r
2930                         int oldIndex = -1;\r
2931                         while ((indexOf = stemp.IndexOf ("isnull", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2932 \r
2933                                 oldIndex = indexOf;\r
2934                                 bool failed = false;\r
2935 \r
2936                                 // Check is or part of column name\r
2937                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2938                                         continue;\r
2939 \r
2940                                 // is the element part of string element\r
2941                                 if (IsPartOfStringElement (stemp, indexOf))\r
2942                                         continue;\r
2943                                 \r
2944                                 return true;\r
2945                         }\r
2946                 \r
2947                         return false;                   \r
2948                 }\r
2949 \r
2950                 private bool FindSubstringElement (string s)\r
2951                 {\r
2952                         string stemp = s.ToLower ();\r
2953                         int indexOf = stemp.IndexOf ("substring");\r
2954 \r
2955                         if (indexOf == -1)\r
2956                                 return false;\r
2957 \r
2958                         int oldIndex = -1;\r
2959                         while ((indexOf = stemp.IndexOf ("substring", oldIndex + 1)) != -1 && indexOf > oldIndex) {\r
2960 \r
2961                                 oldIndex = indexOf;\r
2962                                 bool failed = false;\r
2963 \r
2964                                 // Check is or part of column name\r
2965                                 if (indexOf != 0 && stemp [indexOf - 1] != ' ')\r
2966                                         continue;\r
2967 \r
2968                                 // is the element part of string element\r
2969                                 if (IsPartOfStringElement (stemp, indexOf))\r
2970                                         continue;\r
2971 \r
2972                                 return true;\r
2973                         }\r
2974                 \r
2975                         return false;                   \r
2976                 }\r
2977 \r
2978                 private bool FindInElement (string s, ref string s1, ref string s2)\r
2979                 {\r
2980                         string stemp = s.ToLower ();\r
2981                         int indexOf = stemp.IndexOf ("in");\r
2982 \r
2983                         if (indexOf == -1)\r
2984                                 return false;\r
2985 \r
2986                         int oldIndex = -1;\r
2987                         while ((indexOf = stemp.IndexOf ("in", oldIndex + 1)) != -1 && indexOf > oldIndex) \r
2988                         {\r
2989                                 oldIndex = indexOf;\r
2990                                 \r
2991                                 // check is the 'and' element part of string element\r
2992                                 if (IsPartOfStringElement (stemp, indexOf))\r
2993                                         continue;\r
2994 \r
2995 \r
2996                                 // Check is or part of something else for example column name\r
2997                                 if (indexOf != 0) \r
2998                                 {       \r
2999                                         if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')\r
3000                                                 continue;\r
3001                                 }\r
3002                                 \r
3003                                 if (indexOf < stemp.Length + 2) \r
3004                                 {\r
3005                                         if (stemp [indexOf + 2] != ' ' && stemp [indexOf + 2] != '\'')\r
3006                                                 continue;\r
3007                                 }\r
3008 \r
3009                                 if (IsPartOfFunction (stemp, indexOf))\r
3010                                         continue;\r
3011 \r
3012                                 s1 = s.Substring (0, indexOf).Trim ();\r
3013                                 s2 = s.Substring (indexOf + 2).Trim ();\r
3014                                 return true;\r
3015                         }\r
3016                 \r
3017                         return false;                   \r
3018                 }\r
3019 \r
3020                 \r
3021                 #endregion // CheckElement methods\r
3022 \r
3023                 #region CreateElement methods\r
3024 \r
3025                 // \r
3026                 // These methods are going to be removed when way of parsing is changed\r
3027                 //\r
3028 \r
3029                 private void CreateOrElement (string s1, string s2, string inside) \r
3030                 {\r
3031                         CheckParenthesis (inside, ref s1, ref s2);\r
3032                         Elements.Add (new ExpressionOr (s1.Trim (), s2.Trim ()));\r
3033                 }\r
3034 \r
3035                 private void CreateAndElement (string s1, string s2, string inside)\r
3036                 {\r
3037                         CheckParenthesis (inside, ref s1, ref s2);\r
3038                         Elements.Add (new ExpressionAnd (s1.Trim (), s2.Trim ()));\r
3039                 }\r
3040 \r
3041                 private void CreateLikeElement (string s1, string s2, string inside)\r
3042                 {\r
3043                         CheckParenthesis (inside, ref s1, ref s2);\r
3044                         Elements.Add (new ExpressionLike (s1.Trim (), s2.Trim ()));\r
3045                 }\r
3046 \r
3047                 private void CreateInElement (string s1, string s2, string inside)\r
3048                 {\r
3049                         CheckParenthesis (inside, ref s1, ref s2);\r
3050                         Elements.Add (new ExpressionIn (s1.Trim (), s2.Trim ()));\r
3051                 }\r
3052 \r
3053                 private void CreateEqualsElement (string s1, string s2, string inside)\r
3054                 {\r
3055                         CheckParenthesis (inside, ref s1, ref s2);\r
3056                         Elements.Add (new ExpressionEquals (s1.Trim (), s2.Trim ()));                   \r
3057                 }\r
3058 \r
3059                 private void CreateUnequalsElement (string s1, string s2, string inside)\r
3060                 {\r
3061                         CheckParenthesis (inside, ref s1, ref s2);\r
3062                         Elements.Add (new ExpressionUnequals (s1.Trim (), s2.Trim ()));\r
3063                 }\r
3064 \r
3065                 private void CreateLessThanElement (string s1, string s2, string inside)\r
3066                 {\r
3067                         CheckParenthesis (inside, ref s1, ref s2);\r
3068                         Elements.Add (new ExpressionLessThan (s1.Trim (), s2.Trim ()));\r
3069                 }\r
3070 \r
3071                 private void CreateLessThanOrEqualElement (string s1, string s2, string inside)\r
3072                 {\r
3073                         CheckParenthesis (inside, ref s1, ref s2);\r
3074                         Elements.Add (new ExpressionLessThanOrEqual (s1.Trim (), s2.Trim ()));\r
3075                 }\r
3076 \r
3077                 private void CreateGreaterThanElement (string s1, string s2, string inside)\r
3078                 {\r
3079                         CheckParenthesis (inside, ref s1, ref s2);\r
3080                         Elements.Add (new ExpressionGreaterThan (s1.Trim (), s2.Trim ()));\r
3081                 }\r
3082 \r
3083 \r
3084                 private void CreateGreaterThanOrEqualElement (string s1, string s2, string inside)\r
3085                 {\r
3086                         CheckParenthesis (inside, ref s1, ref s2);\r
3087                         Elements.Add (new ExpressionGreaterThanOrEqual (s1.Trim (), s2.Trim ()));\r
3088                 }\r
3089 \r
3090                 private void CreateAdditionElement (string s1, string s2,  string inside)\r
3091                 {\r
3092                         CheckParenthesis (inside, ref s1, ref s2);                      \r
3093                         Elements.Add (new ExpressionAddition (s1.Trim (), s2.Trim ()));\r
3094                 }\r
3095 \r
3096                 private void CreateSubtractionElement (string s1, string s2,  string inside)\r
3097                 {\r
3098                         CheckParenthesis (inside, ref s1, ref s2);                      \r
3099                         Elements.Add (new ExpressionSubtraction (s1.Trim (), s2.Trim ()));\r
3100                 }\r
3101 \r
3102                 private void CreateMultiplyElement (string s1, string s2, string inside)\r
3103                 {\r
3104                         CheckParenthesis (inside, ref s1, ref s2);\r
3105                         Elements.Add (new ExpressionMultiply (s1.Trim (), s2.Trim ()));\r
3106                 }\r
3107 \r
3108                 private void CreateDivideElement (string s1, string s2, string inside)\r
3109                 {\r
3110                         CheckParenthesis (inside, ref s1, ref s2);\r
3111                         Elements.Add (new ExpressionDivide (s1.Trim (), s2.Trim ()));\r
3112                 }\r
3113 \r
3114                 private void CreateModulusElement (string s1, string s2, string inside)\r
3115                 {\r
3116                         CheckParenthesis (inside, ref s1, ref s2);\r
3117                         Elements.Add (new ExpressionModulus (s1.Trim (), s2.Trim ()));\r
3118                 }                       \r
3119 \r
3120                 #endregion // CreateElemnt methods\r
3121 \r
3122                 #region Little helppers\r
3123 \r
3124                 private void CheckParenthesis (string inside, ref string s1, ref string s2)\r
3125                 {\r
3126                         if (s1 == string.Empty && inside != string.Empty)\r
3127                                 s1 = inside;\r
3128                         else if (s2 == string.Empty && inside != string.Empty)\r
3129                                 s2 = inside;    \r
3130                 }\r
3131 \r
3132 \r
3133                 /// <summary>\r
3134                 ///  Checks is the element part of stringelement\r
3135                 /// </summary>\r
3136                 private bool IsPartOfStringElement (string s, int indexOf)\r
3137                 {\r
3138                         // count how many '-charachters are before or. If count is odd it means or IS between quotes\r
3139                         int quotes = 0;\r
3140                         for (int i = indexOf - 1; i >= 0; i--) {\r
3141                                 if (s [i] == '\'')\r
3142                                         quotes++;\r
3143                         }\r
3144                         \r
3145                         if (quotes % 2 != 0)\r
3146                                 return true;\r
3147                         else \r
3148                                 return false;\r
3149                 }\r
3150 \r
3151                 /// <summary>\r
3152                 ///  Checks is the element part of column table\r
3153                 /// </summary>\r
3154                 private bool IsPartOfColumnName (string s, int indexOf)\r
3155                 {\r
3156                         for (int i = indexOf; i >= 0; i--) {\r
3157                                 \r
3158                                 // If the element is between [] it is part of columnname\r
3159                                 if (s [i] == '\'' || s [i] == ']') {\r
3160                                         break;\r
3161                                 }\r
3162                                 else if (s [i] == '[') {\r
3163                                         return true;\r
3164                                 }\r
3165                         }\r
3166 \r
3167                         return false;\r
3168                 }\r
3169 \r
3170 \r
3171                 /// <summary>\r
3172                 ///  Checks are element part of function\r
3173                 /// </summary>\r
3174                 private bool IsPartOfFunction (string s, int indexOf)\r
3175                 {\r
3176 \r
3177                         // \r
3178                         // If ',' or '\''  comes before '(' this element is not part of function's parameters\r
3179                         //\r
3180                         \r
3181                         for (int i = indexOf; i >= 0; i--) {\r
3182                                 \r
3183                                 if (s [i] == '(' || s [i] == ',') {\r
3184                                         return true;\r
3185                                 }\r
3186                                 else if (s [i] == ')') {\r
3187                                         break;\r
3188                                 }\r
3189                         }\r
3190 \r
3191                         return false;\r
3192                 }\r
3193 \r
3194                 #endregion // Little helppers\r
3195         }        \r
3196 }\r