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