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