2 // System.Data.ExpressionElement
\r
5 // Ville Palo <vi64pa@kolumbus.fi>
\r
7 // Copyright (C) Ville Palo, 2003
\r
9 // TODO: - Some functionelements and aggregates.
\r
10 // - New parsing style.
\r
16 using System.Reflection;
\r
18 using System.Collections;
\r
20 namespace System.Data
\r
23 /// The main element which includes whole expression
\r
25 internal class ExpressionMainElement : ExpressionElement
\r
30 public ExpressionMainElement (string s)
\r
32 s = ExpressionElement.ValidateExpression (s);
\r
33 ParseExpression (s);
\r
36 public override bool Test (DataRow Row)
\r
39 foreach (ExpressionElement El in Elements)
\r
52 // O_P_E_R_A_T_O_R_S
\r
58 internal class ExpressionEquals : ExpressionElement
\r
61 public ExpressionEquals (string exp1, string exp2)
\r
65 ParseExpression (exp1);
\r
66 ParseExpression (exp2);
\r
69 public override bool Test (DataRow Row)
\r
72 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
73 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
75 return ExpressionElement.Compare (E1, E2, Row) == 0;
\r
82 internal class ExpressionLessThan : ExpressionElement
\r
85 public ExpressionLessThan (string exp1, string exp2)
\r
89 ParseExpression (exp1);
\r
90 ParseExpression (exp2);
\r
93 public override bool Test (DataRow Row)
\r
96 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
97 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
99 return ExpressionElement.Compare (E1, E2, Row) < 0;
\r
106 internal class ExpressionLessThanOrEqual : ExpressionElement
\r
109 public ExpressionLessThanOrEqual (string exp1, string exp2)
\r
113 ParseExpression (exp1);
\r
114 ParseExpression (exp2);
\r
117 public override bool Test (DataRow Row)
\r
120 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
121 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
123 return ExpressionElement.Compare (E1, E2, Row) <= 0;
\r
130 internal class ExpressionGreaterThan : ExpressionElement
\r
133 public ExpressionGreaterThan (string exp1, string exp2)
\r
137 ParseExpression (exp1);
\r
138 ParseExpression (exp2);
\r
141 public override bool Test (DataRow Row)
\r
144 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
145 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
147 return ExpressionElement.Compare (E1, E2, Row) > 0;
\r
154 internal class ExpressionGreaterThanOrEqual : ExpressionElement
\r
157 public ExpressionGreaterThanOrEqual (string exp1, string exp2)
\r
161 ParseExpression (exp1);
\r
162 ParseExpression (exp2);
\r
165 public override bool Test (DataRow Row)
\r
168 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
169 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
171 return ExpressionElement.Compare (E1, E2, Row) >= 0;
\r
178 internal class ExpressionUnequals : ExpressionElement
\r
181 public ExpressionUnequals (string exp1, string exp2)
\r
185 ParseExpression (exp1);
\r
186 ParseExpression (exp2);
\r
189 public override bool Test (DataRow Row)
\r
192 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
193 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
195 return ExpressionElement.Compare (E1, E2, Row) != 0;
\r
201 /// Class for LIKE-operator
\r
203 internal class ExpressionLike : ExpressionElement
\r
206 public ExpressionLike (string exp1, string exp2)
\r
208 ParseExpression (exp1);
\r
209 ParseExpression (exp2);
\r
212 public override bool Test (DataRow Row)
\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
220 if (value1.GetType () != typeof (string) || value2.GetType () != typeof (string))
\r
221 throw new Exception (); // TODO: what exception
\r
223 string operand1 = value1.ToString ();
\r
224 string operand2 = value2.ToString ();
\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
235 indexOf = operand2.IndexOf ("*");
\r
236 while (indexOf != -1)
\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
244 operand2 = operand2.Remove (indexOf + 1, 1);
\r
245 operand2 = operand2.Remove (indexOf -1, 1);
\r
249 indexOf = operand2.IndexOf ("*", oldIndex);
\r
253 indexOf = operand2.IndexOf ("%");
\r
254 while (indexOf != -1)
\r
257 oldIndex = indexOf + 1;
\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
263 operand2 = operand2.Remove (indexOf + 1, 1);
\r
264 operand2 = operand2.Remove (indexOf -1, 1);
\r
268 indexOf = operand2.IndexOf ("%", oldIndex);
\r
271 int len2 = operand2.Length;
\r
272 int startIndex = 0;
\r
273 while ((startIndex + len2) <= operand1.Length)
\r
275 if (String.Compare (operand1.Substring (startIndex, len2), operand2, !Row.Table.CaseSensitive) == 0)
\r
288 internal class ExpressionOr : ExpressionElement
\r
290 public ExpressionOr (string exp1, string exp2)
\r
292 ParseExpression (exp1);
\r
293 ParseExpression (exp2);
\r
296 public override bool Test (DataRow Row)
\r
298 foreach (ExpressionElement El in Elements)
\r
311 internal class ExpressionAnd : ExpressionElement
\r
313 public ExpressionAnd (string exp1, string exp2)
\r
315 ParseExpression (exp1);
\r
316 ParseExpression (exp2);
\r
319 public override object Result (DataRow Row)
\r
325 public override bool Test (DataRow Row)
\r
327 foreach (ExpressionElement El in Elements)
\r
329 if (!El.Test (Row))
\r
339 // A_R_I_T_H_M_E_T_I_C O_P_E_R_A_T_O_R_S
\r
345 internal class ExpressionAddition : ExpressionElement
\r
347 public ExpressionAddition (string exp1, string exp2)
\r
351 ParseExpression (exp1);
\r
352 ParseExpression (exp2);
\r
355 public override Type ResultType (DataRow Row)
\r
357 Type ResultType = typeof (string);
\r
358 ExpressionElement exp1Temp = ((ExpressionElement)Elements [0]);
\r
359 ExpressionElement exp2Temp = ((ExpressionElement)Elements [1]);
\r
361 if (exp1Temp.ResultType (Row) == typeof (string) || exp2Temp.ResultType (Row) == typeof (string))
\r
362 ResultType = typeof (string);
\r
364 else if (exp1Temp.ResultType (Row) == typeof (long) || exp2Temp.ResultType (Row) == typeof (long))
\r
365 ResultType = typeof (long);
\r
367 else if (exp1Temp.ResultType (Row) == typeof (int) || exp2Temp.ResultType (Row) == typeof (int))
\r
368 ResultType = typeof (int);
\r
373 public override object Result (DataRow Row)
\r
375 return CalculateResult (Row);
\r
378 protected override object Calculate (object value1, object value2, Type TempType)
\r
380 object Result = null;
\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
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
410 //else if (TempType == typeof (DateTime))
\r
411 // Result = (DateTime)value1 + (DateTime)value2;
\r
417 // This method is shouldnt never invoked
\r
418 public override bool Test (DataRow Row)
\r
420 throw new EvaluateException ();
\r
427 internal class ExpressionSubtraction : ExpressionElement
\r
429 public ExpressionSubtraction (string exp1, string exp2)
\r
433 ParseExpression (exp1);
\r
434 ParseExpression (exp2);
\r
437 public override object Result (DataRow Row)
\r
439 return CalculateResult (Row);
\r
442 // This method is shouldnt never invoked
\r
443 public override bool Test (DataRow Row)
\r
445 throw new EvaluateException ();
\r
448 protected override object Calculate (object value1, object value2, Type TempType)
\r
450 object Result = null;
\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
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
481 //else if (TempType == typeof (DateTime))
\r
482 // Result = (DateTime)value1 - (DateTime)value2;
\r
491 internal class ExpressionMultiply : ExpressionElement
\r
493 public ExpressionMultiply (string exp1, string exp2)
\r
497 ParseExpression (exp1);
\r
498 ParseExpression (exp2);
\r
501 public override Type ResultType (DataRow Row)
\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
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
513 else if (t1 == typeof (long) || t2 == typeof (long))
\r
514 ResultType = typeof (long);
\r
516 else if (t1 == typeof (int) || t2 == typeof (int))
\r
517 ResultType = typeof (int);
\r
522 public override object Result (DataRow Row)
\r
524 return CalculateResult (Row);
\r
527 public override bool Test (DataRow Row)
\r
529 throw new EvaluateException ();
\r
532 protected override object Calculate (object value1, object value2, Type TempType)
\r
534 object Result = null;
\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
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
562 //else if (TempType == typeof (DateTime))
\r
563 // Result = (DateTime)value1 * (DateTime)value2;
\r
573 internal class ExpressionDivide : ExpressionElement
\r
575 public ExpressionDivide (string exp1, string exp2)
\r
579 ParseExpression (exp1);
\r
580 ParseExpression (exp2);
\r
583 public override object Result (DataRow Row)
\r
585 return CalculateResult (Row);
\r
588 // This method is shouldnt never invoked
\r
589 public override bool Test (DataRow Row)
\r
591 throw new EvaluateException ();
\r
594 protected override object Calculate (object value1, object value2, Type TempType)
\r
596 object Result = null;
\r
598 if (TempType == typeof (long))
\r
599 Result = (long)value1 / (long)value2;
\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
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
627 //else if (TempType == typeof (DateTime))
\r
628 // Result = (DateTime)value1 / (DateTime)value2;
\r
637 internal class ExpressionModulus : ExpressionElement
\r
639 public ExpressionModulus (string exp1, string exp2)
\r
643 ParseExpression (exp1);
\r
644 ParseExpression (exp2);
\r
647 public override object Result (DataRow Row)
\r
649 return CalculateResult (Row);
\r
652 // This method is shouldnt never invoked
\r
653 public override bool Test (DataRow Row)
\r
655 throw new EvaluateException ();
\r
658 protected override object Calculate (object value1, object value2, Type TempType)
\r
660 object Result = null;
\r
662 if (TempType == typeof (long))
\r
663 Result = (long)value1 % (long)value2;
\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
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
691 //else if (TempType == typeof (DateTime))
\r
692 // Result = (DateTime)value1 / (DateTime)value2;
\r
699 // _____A_G_G_R_E_G_A_T_E_S_____
\r
702 internal class ExpressionAggregate : ExpressionElement
\r
705 public ExpressionAggregate()
\r
709 public ExpressionAggregate(string s)
\r
711 s = ExpressionElement.ValidateExpression (s);
\r
712 ParseExpression (s);
\r
716 public override bool Test (DataRow Row)
\r
718 throw new EvaluateException ();
\r
721 public override object Result(DataRow Row)
\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
728 public virtual object Result(DataRow[] rows)
\r
730 return ((ExpressionAggregate)Elements[0]).Result(rows);
\r
734 protected virtual void ParseParameters (string s)
\r
736 string stemp = s.ToLower ();
\r
737 bool inString = false;
\r
741 while (!s.StartsWith ("("))
\r
742 s = s.Remove (0, 1);
\r
745 s = s.Remove (0, 1);
\r
747 int parentheses = 0;
\r
748 for (int i = 0; i < s.Length; i++)
\r
752 inString = !inString;
\r
753 else if (s [i] == '(')
\r
755 else if (s [i] == ')')
\r
758 if ((s [i] == ',' || s [i] == ')') && !inString && parentheses == -1)
\r
759 { // Parameter changed
\r
763 p1 = s.Substring (0, i);
\r
770 throw new Exception ();
\r
772 ParseExpression (p1);
\r
778 /// Class for Sum (column_Name)
\r
780 internal class ExpressionSum : ExpressionAggregate
\r
782 public ExpressionSum (string exp1)
\r
784 ParseParameters (exp1);
\r
787 public override object Result(DataRow[] rows)
\r
789 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
790 object value1 = E1.Result (rows[0]);
\r
791 Type t1 = value1.GetType ();
\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
797 if (E1 is ExpressionSingleElement)
\r
800 // This should be optimized somehow
\r
801 for (int i = 0; i < rows.Length; i++)
\r
804 // TODO: other types and exceptions
\r
805 object v = E1.Result (rows[i]);
\r
808 if (v == null || v == DBNull.Value)
\r
811 if (t1 == typeof (long))
\r
813 result = (long)result + (long)v;
\r
815 else if (t1 == typeof (int))
\r
817 result = (int)result + (int)v;
\r
819 else if (t1 == typeof (short))
\r
821 result = (short)result + (short)v;
\r
823 else if (t1 == typeof (double))
\r
825 result = (double)result + (double)v;
\r
827 else if (t1 == typeof (float))
\r
829 result = (float)result + (float)v;
\r
832 throw new NotImplementedException ();
\r
841 // Copy: This method is copy-paste in every Aggregate class.
\r
846 /// Class for Avg (column_Name)
\r
848 internal class ExpressionAvg : ExpressionAggregate
\r
850 public ExpressionAvg (string exp1)
\r
852 ParseParameters (exp1);
\r
855 public override object Result(DataRow[] rows)
\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
862 if (E1 is ExpressionSingleElement)
\r
866 // This should be optimized somehow
\r
867 for (int i = 0; i < rows.Length; i++)
\r
870 // TODO: other types and exceptions
\r
871 object v = E1.Result (rows[i]);
\r
873 if (v == null || v == DBNull.Value)
\r
878 if (result == null)
\r
881 if (t1 == typeof (long))
\r
883 result = (long)result + (long)v;
\r
885 else if (t1 == typeof (int))
\r
887 result = (int)result + (int)v;
\r
889 else if (t1 == typeof (short))
\r
891 result = (short)result + (short)v;
\r
893 else if (t1 == typeof (double))
\r
895 result = (double)result + (double)v;
\r
897 else if (t1 == typeof (float))
\r
899 result = (float)result + (float)v;
\r
902 throw new NotImplementedException ();
\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
921 /// This is used from ExpressionStdDev for evaluating avg.
\r
923 public ExpressionAvg (ExpressionElement E)
\r
931 /// Class for Min (column_Name)
\r
933 internal class ExpressionMin : ExpressionAggregate
\r
935 public ExpressionMin (string exp1)
\r
937 ParseParameters (exp1);
\r
940 public override object Result(DataRow[] rows)
\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
947 if (E1 is ExpressionSingleElement)
\r
951 // This should be optimized somehow
\r
952 for (int i = 0; i < rows.Length; i++)
\r
955 // TODO: other types and exceptions
\r
956 object v = E1.Result (rows[i]);
\r
958 if (v == null || v == DBNull.Value)
\r
963 if (result == null)
\r
966 object CompResult = t1.InvokeMember ("CompareTo", BindingFlags.Default |
\r
967 BindingFlags.InvokeMethod, null,
\r
969 new object [] {result});
\r
971 if ((int)CompResult < 0)
\r
984 /// Class for Max (column_Name)
\r
986 internal class ExpressionMax : ExpressionAggregate
\r
988 public ExpressionMax (string exp1)
\r
990 ParseParameters (exp1);
\r
993 public override object Result(DataRow[] rows)
\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
1000 if (E1 is ExpressionSingleElement)
\r
1004 // This should be optimized somehow
\r
1005 for (int i = 0; i < rows.Length; i++)
\r
1008 // TODO: other types and exceptions
\r
1009 object v = E1.Result (rows[i]);
\r
1011 if (v == null || v == DBNull.Value)
\r
1014 t1 = v.GetType ();
\r
1016 if (result == null)
\r
1019 object CompResult = t1.InvokeMember ("CompareTo", BindingFlags.Default |
\r
1020 BindingFlags.InvokeMethod, null,
\r
1022 new object [] {result});
\r
1024 if ((int)CompResult > 0)
\r
1038 /// Class for count (column)
\r
1040 internal class ExpressionCount : ExpressionAggregate
\r
1042 public ExpressionCount (string exp1)
\r
1044 ParseParameters (exp1);
\r
1047 public override object Result(DataRow[] rows)
\r
1049 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1052 if (E1 is ExpressionSingleElement)
\r
1053 count = rows.Length;
\r
1058 public override object Result (DataRow Row)
\r
1060 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1063 if (E1 is ExpressionSingleElement)
\r
1066 count = Row.Table.Rows.Count;
\r
1075 /// Class for StdDev (column)
\r
1077 internal class ExpressionStdev : ExpressionAggregate
\r
1079 public ExpressionStdev (string exp1)
\r
1081 ParseParameters (exp1);
\r
1084 public override object Result(DataRow[] rows)
\r
1086 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1087 ExpressionAvg Avg = new ExpressionAvg (E1);
\r
1089 object tempAvg = Avg.Result (rows[0]);
\r
1092 double result = 0;
\r
1094 if (tempAvg.GetType () == typeof (int))
\r
1095 avg = (double)(int)tempAvg;
\r
1097 if (E1 is ExpressionSingleElement)
\r
1100 for (int i = 0; i <rows.Length; i++)
\r
1102 // (value - avg)²
\r
1103 object v = E1.Result (rows[i]);
\r
1105 if (v == null || v == DBNull.Value)
\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
1115 throw new NotImplementedException ();
\r
1117 result += Math.Pow (sum, 2);
\r
1120 result = result / (rows.Length - 1);
\r
1121 result = Math.Sqrt (result);
\r
1131 /// Class for Var (column)
\r
1133 internal class ExpressionVar : ExpressionAggregate
\r
1135 public ExpressionVar (string exp1)
\r
1137 ParseParameters (exp1);
\r
1140 public override object Result(DataRow[] rows)
\r
1142 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1143 ExpressionAvg Avg = new ExpressionAvg (E1);
\r
1145 object tempAvg = Avg.Result (rows[0]);
\r
1148 double result = 0;
\r
1150 if (tempAvg.GetType () == typeof (int))
\r
1151 avg = (double)(int)tempAvg;
\r
1153 if (E1 is ExpressionSingleElement)
\r
1156 for (int i = 0; i < rows.Length; i++)
\r
1160 // (value - avg)²
\r
1161 object v = E1.Result (rows[i]);
\r
1163 if (v == null || v == DBNull.Value)
\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
1173 throw new NotImplementedException ();
\r
1175 result += Math.Pow (sum, 2);
\r
1178 result = result / (rows.Length - 1);
\r
1188 // _____F_U_ N_C_T_I_O_N_S_______
\r
1192 /// Class for len (string) function
\r
1194 internal class ExpressionLen : ExpressionElement
\r
1196 public ExpressionLen (string exp1)
\r
1198 _ResultType = typeof (int);
\r
1199 ParseParameters (exp1);
\r
1202 public override object Result (DataRow Row)
\r
1204 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1205 object value1 = E1.Result (Row);
\r
1207 return value1.ToString ().Length;
\r
1210 public override bool Test (DataRow Row)
\r
1212 throw new EvaluateException ();
\r
1215 public void ParseParameters (string s)
\r
1217 string stemp = s.ToLower ();
\r
1218 bool inString = false;
\r
1222 while (!s.StartsWith ("("))
\r
1223 s = s.Remove (0, 1);
\r
1226 s = s.Remove (0, 1);
\r
1227 int parentheses = 0;
\r
1228 for (int i = 0; i < s.Length; i++)
\r
1231 if (s [i] == '\'')
\r
1232 inString = !inString;
\r
1233 else if (s [i] == '(')
\r
1235 else if (s [i] == ')')
\r
1238 if ((s [i] == ',' || s [i] == ')') && !inString && parentheses == -1)
\r
1239 { // Parameter changed
\r
1243 p1 = s.Substring (0, i);
\r
1250 throw new Exception ();
\r
1252 ParseExpression (p1);
\r
1257 /// Class for iif (exp1, truepart, falsepart) function
\r
1259 internal class ExpressionIif : ExpressionElement
\r
1261 public ExpressionIif (string exp)
\r
1263 ParseParameters (exp);
\r
1266 public override object Result (DataRow Row)
\r
1268 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1269 ExpressionElement E2 = ((ExpressionElement)Elements [1]);
\r
1270 ExpressionElement E3 = ((ExpressionElement)Elements [2]);
\r
1272 if (E1.Test (Row)) // expression
\r
1273 return E2.Result (Row); // truepart
\r
1275 return E3.Result (Row); // false part
\r
1278 // This method is shouldnt never invoked
\r
1279 public override bool Test (DataRow Row)
\r
1281 throw new EvaluateException ();
\r
1284 public override Type ResultType (DataRow Row)
\r
1286 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1287 ExpressionElement E2 = ((ExpressionElement)Elements [1]);
\r
1288 ExpressionElement E3 = ((ExpressionElement)Elements [2]);
\r
1290 if (E1.Test (Row)) // expression
\r
1291 return E2.Result (Row).GetType (); // truepart
\r
1293 return E3.Result (Row).GetType (); // false part
\r
1297 /// Parses expressions in parameters (exp, truepart, falsepart)
\r
1299 private void ParseParameters (string s)
\r
1301 bool inString = false;
\r
1302 string stemp = s.ToLower ();
\r
1306 s = s.Substring (stemp.IndexOf ("iif") + 3);
\r
1309 while (!s.StartsWith ("("))
\r
1310 s = s.Remove (0, 1);
\r
1313 s = s.Remove (0, 1);
\r
1314 int parentheses = 0;
\r
1315 for (int i = 0; i < s.Length; i++)
\r
1318 if (s [i] == '\'')
\r
1319 inString = !inString;
\r
1320 else if (s [i] == '(')
\r
1322 else if (s [i] == ')')
\r
1325 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1326 (s [i] == ')' && i == (s.Length -1)))
\r
1327 { // Parameter changed
\r
1331 p1 = s.Substring (0, i);
\r
1332 s = s.Substring (i + 1);
\r
1336 else if (p2 == null)
\r
1338 p2 = s.Substring (0, i);
\r
1339 s = s.Substring (i + 1);
\r
1343 else if (p3 == null)
\r
1345 p3 = s.Substring (0, i);
\r
1346 s = s.Substring (i + 1);
\r
1351 throw new Exception (); // FIXME: What exception
\r
1355 if (p1 == null || p2 == null || p3 == null)
\r
1356 throw new Exception ();
\r
1358 ParseExpression (p1);
\r
1359 ParseExpression (p2);
\r
1360 ParseExpression (p3);
\r
1365 /// Class for isnull (expression, returnvalue) function
\r
1367 internal class ExpressionIsNull : ExpressionElement
\r
1369 public ExpressionIsNull (string exp)
\r
1371 ParseParameters (exp);
\r
1374 public override object Result (DataRow Row)
\r
1376 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1377 ExpressionElement E2 = (ExpressionElement)Elements [1];
\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
1387 public override Type ResultType (DataRow Row)
\r
1389 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1390 ExpressionElement E2 = (ExpressionElement)Elements [1];
\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
1397 return R1.GetType ();
\r
1401 /// IsNull function does not return boolean value, so throw exception
\r
1403 public override bool Test (DataRow Row)
\r
1405 throw new EvaluateException ();
\r
1409 /// Parses parameters of function and invoke ParseExpression methods
\r
1411 private void ParseParameters (string s)
\r
1413 bool inString = false;
\r
1414 string stemp = s.ToLower ();
\r
1418 s = s.Substring (stemp.IndexOf ("isnull") + 6);
\r
1421 while (!s.StartsWith ("("))
\r
1422 s = s.Remove (0, 1);
\r
1425 s = s.Remove (0, 1);
\r
1426 int parentheses = 0;
\r
1427 for (int i = 0; i < s.Length; i++)
\r
1430 if (s [i] == '\'')
\r
1431 inString = !inString;
\r
1432 else if (s [i] == '(')
\r
1434 else if (s [i] == ')')
\r
1437 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1438 (s [i] == ')' && i == (s.Length -1)))
\r
1439 { // Parameter changed
\r
1443 p1 = s.Substring (0, i);
\r
1444 s = s.Substring (i + 1);
\r
1448 else if (p2 == null)
\r
1450 p2 = s.Substring (0, i);
\r
1451 s = s.Substring (i + 1);
\r
1456 throw new Exception (); // FIXME: What exception
\r
1460 if (p1 == null || p2 == null)
\r
1461 throw new Exception ();
\r
1463 ParseExpression (p1);
\r
1464 ParseExpression (p2);
\r
1469 /// Class for Substring (expression, start, length) function
\r
1471 internal class ExpressionSubstring : ExpressionElement
\r
1473 public ExpressionSubstring (string exp)
\r
1475 ParseParameters (exp);
\r
1476 _ResultType = typeof (string);
\r
1479 public override object Result (DataRow Row)
\r
1481 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1482 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
1483 ExpressionElement E3 = (ExpressionElement)Elements [2];
\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
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
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
1503 string str = value1.ToString ();
\r
1504 int start = (int)value2;
\r
1505 int length = (int)value3;
\r
1507 if (str.Length < start)
\r
1508 str = string.Empty;
\r
1511 if ((start + length - 1) > str.Length)
\r
1512 str = str.Substring (start - 1);
\r
1514 str = str.Substring (start - 1, length);
\r
1521 /// IsNull function does not return boolean value, so throw exception
\r
1523 public override bool Test (DataRow Row)
\r
1525 throw new EvaluateException ();
\r
1529 /// Parses parameters of function and invoke ParseExpression methods
\r
1531 private void ParseParameters (string s)
\r
1533 bool inString = false;
\r
1534 string stemp = s.ToLower ();
\r
1539 s = s.Substring (stemp.IndexOf ("substring") + 9);
\r
1542 while (!s.StartsWith ("("))
\r
1543 s = s.Remove (0, 1);
\r
1546 s = s.Remove (0, 1);
\r
1547 int parentheses = 0;
\r
1548 for (int i = 0; i < s.Length; i++)
\r
1551 if (s [i] == '\'')
\r
1552 inString = !inString;
\r
1553 else if (s [i] == '(')
\r
1555 else if (s [i] == ')')
\r
1559 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1560 (s [i] == ')' && i == (s.Length -1)))
\r
1561 { // Parameter changed
\r
1565 p1 = s.Substring (0, i);
\r
1566 s = s.Substring (i + 1);
\r
1570 else if (p2 == null)
\r
1572 p2 = s.Substring (0, i);
\r
1573 s = s.Substring (i + 1);
\r
1577 else if (p3 == null)
\r
1579 p3 = s.Substring (0, i);
\r
1580 s = s.Substring (i + 1);
\r
1585 throw new Exception (); // FIXME: What exception
\r
1589 if (p1 == null || p2 == null)
\r
1590 throw new Exception ();
\r
1592 ParseExpression (p1);
\r
1593 ParseExpression (p2);
\r
1594 ParseExpression (p3);
\r
1599 /// Class for In (exp, exp, exp, ...) function
\r
1601 internal class ExpressionIn : ExpressionElement
\r
1603 public ExpressionIn (string exp1, string exp2)
\r
1605 ParseExpression(exp1);
\r
1606 ParseParameters (exp2);
\r
1610 /// IsNull function does not return boolean value, so throw exception
\r
1612 public override bool Test (DataRow Row)
\r
1614 ExpressionElement E;
\r
1615 ExpressionElement columnElement = (ExpressionElement)Elements [0];
\r
1617 for (int i = 1; i < Elements.Count; i++)
\r
1619 E = (ExpressionElement)Elements [i];
\r
1620 if(ExpressionElement.Compare (columnElement, E, Row) == 0)
\r
1627 /// Parses parameters of function and invoke ParseExpression methods
\r
1629 private void ParseParameters (string s)
\r
1631 bool inString = false;
\r
1632 ArrayList parameters = new ArrayList();
\r
1635 while (!s.StartsWith ("("))
\r
1636 s = s.Remove (0, 1);
\r
1639 s = s.Remove (0, 1);
\r
1640 int parentheses = 0;
\r
1641 for (int i = 0; i < s.Length; i++)
\r
1644 if (s [i] == '\'')
\r
1645 inString = !inString;
\r
1646 else if (s [i] == '(')
\r
1648 else if (s [i] == ')')
\r
1652 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1653 (s [i] == ')' && i == (s.Length -1)))
\r
1655 parameters.Add(s.Substring (0, i));
\r
1656 s = s.Substring (i + 1);
\r
1661 for (int i = 0; i < parameters.Count; i++)
\r
1662 ParseExpression((string)parameters[i]);
\r
1667 /// Class for just one element for example string, int, ...
\r
1669 internal class ExpressionSingleElement : ExpressionElement
\r
1671 private object Element = null;
\r
1673 public ExpressionSingleElement (string s)
\r
1675 // TODO: Every type should be checked
\r
1676 if (s.StartsWith ("'") && s.EndsWith ("'"))
\r
1678 Element = s.Substring (1, s.Length - 2);
\r
1679 _ResultType = typeof (string);
\r
1681 else if (!Char.IsDigit (s [0]) && s [0] != '-' && s [0] != '+')
\r
1684 _ResultType = typeof (DataColumn);
\r
1686 else if (s.StartsWith ("#") && s.EndsWith ("#"))
\r
1688 Element = DateTime.Parse (s.Substring (1, s.Length - 2));
\r
1689 _ResultType = typeof (DateTime);
\r
1695 Element = int.Parse (s);
\r
1696 _ResultType = typeof (int);
\r
1700 Element = Decimal.Parse (s);
\r
1701 _ResultType = typeof (Decimal);
\r
1706 public override object Result (DataRow Row)
\r
1708 object Result = null;
\r
1709 if (ResultType (Row) == typeof (DataColumn))
\r
1712 if (!Row.Table.Columns.Contains (Element.ToString ()))
\r
1713 throw new EvaluateException ("Column name '" + Element.ToString () + "' not found.");
\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
1729 public override bool Test (DataRow Row)
\r
1731 throw new EvaluateException ();
\r
1736 /// Parent class of all the elements of expression
\r
1738 internal abstract class ExpressionElement
\r
1740 enum OP {OPERATOR, OPERAND};
\r
1741 enum OPERATOR_TYPE {SYMBOLIC, LITERAL, UNDEFINED};
\r
1742 enum OPERAND_TYPE {NUMERIC, STRING, UNDEFINED};
\r
1745 // TODO/FIXME: This class should be inherited more than once. I mean own subclass for operators, functions,...
\r
1748 protected string exp1;
\r
1749 protected string exp2;
\r
1750 protected Type _ResultType;
\r
1752 protected ArrayList Elements = new ArrayList ();
\r
1754 enum AGGREGATE {SUM, AVG, MIN, MAX, COUNT, STDEV, VAR}
\r
1755 //protected ArrayList Singles = new ArrayList ();
\r
1758 /// Tells does the current expressions match to current DataRow
\r
1760 abstract public bool Test (DataRow Row);
\r
1762 public virtual object Result (DataRow Row) {return null;}
\r
1764 public virtual Type ResultType (DataRow Row)
\r
1766 return _ResultType;
\r
1769 protected object CalculateResult (DataRow Row)
\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
1780 if (value1 == DBNull.Value && value2 == DBNull.Value)
\r
1783 // TODO: More types
\r
1785 if (t1 == typeof (string) || t2 == typeof (string))
\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
1795 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1797 Result = Calculate (value1, value2, t1);
\r
1801 protected virtual object Calculate (object value1, object value2, Type TempType)
\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
1810 protected static int Compare (ExpressionElement E1, ExpressionElement E2, DataRow Row)
\r
1812 int ReturnValue = 0;
\r
1814 object value1 = E1.Result (Row);
\r
1815 object value2 = E2.Result (Row);
\r
1817 if ((value1 == null || value1 == DBNull.Value) && (value2 == null || value2 == DBNull.Value))
\r
1819 else if (value2 == null || value2 == DBNull.Value)
\r
1821 else if (value1 == null || value1 == DBNull.Value)
\r
1824 Type t1 = value1.GetType ();
\r
1825 Type t2 = value2.GetType ();
\r
1827 Type RT1 = E1.ResultType (Row);
\r
1828 Type RT2 = E2.ResultType (Row);
\r
1830 if (t1 == typeof (string) || t2 == typeof (string))
\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
1840 if (!Row.Table.CaseSensitive)
\r
1842 value1 = ((string)value1).ToLower ();
\r
1843 value2 = ((string)value2).ToLower ();
\r
1846 else if (t1 != t2)
\r
1849 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1852 object Result = t1.InvokeMember ("CompareTo", BindingFlags.Default |
\r
1853 BindingFlags.InvokeMethod, null,
\r
1855 new object [] {value2});
\r
1856 ReturnValue = (int)Result;
\r
1858 return ReturnValue;
\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
1865 internal static string ValidateExpression (string s)
\r
1868 // TODO: find out nice way to do this. This is NOT nice way :-P
\r
1871 OP op = OP.OPERAND;
\r
1872 OPERATOR_TYPE operatorType = OPERATOR_TYPE.UNDEFINED;
\r
1874 string strOperator = "";
\r
1875 string strOperand = "";
\r
1877 int parentheses = 0;
\r
1878 string newExp = "";
\r
1879 bool isDigit = false;
\r
1880 bool litOperator = false;
\r
1883 for (int i = 0; i < s.Length; i++)
\r
1891 if ((c == '\n' || c == '\t') && quotes == 0)
\r
1894 if (op == OP.OPERAND && c == '(')
\r
1896 else if (op == OP.OPERAND && c == ')')
\r
1899 if (c == ' ' && op == OP.OPERAND && (quotes % 2) == 0 && parentheses == 0)
\r
1903 newExp += strOperand;
\r
1905 strOperator = " ";
\r
1908 if (op == OP.OPERAND)
\r
1911 if (!Char.IsDigit (c) && isDigit && (quotes % 2) == 0)
\r
1914 newExp += strOperand;
\r
1917 operatorType = OPERATOR_TYPE.UNDEFINED;
\r
1923 if (op == OP.OPERATOR)
\r
1927 if (operatorType == OPERATOR_TYPE.UNDEFINED)
\r
1930 if (c == '<' || c == '=' || c == '>' || c == '*' || c == '/' || c == '%'
\r
1931 || c == '-' || c == '+')
\r
1933 operatorType = OPERATOR_TYPE.SYMBOLIC;
\r
1934 else if (c != ' ')
\r
1935 operatorType = OPERATOR_TYPE.LITERAL;
\r
1937 else if (operatorType == OPERATOR_TYPE.SYMBOLIC)
\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
1946 // this is COPY-PASTE
\r
1948 if (!newExp.EndsWith (" ") && !strOperator.StartsWith (" "))
\r
1949 strOperator = " " + strOperator;
\r
1951 newExp += strOperator;
\r
1953 if (Char.IsDigit (c))
\r
1956 strOperand = c.ToString ();
\r
1963 if (operatorType == OPERATOR_TYPE.LITERAL && c == ' ')
\r
1966 newExp += strOperator;
\r
1967 strOperand += " ";
\r
1972 if (Char.IsDigit (c) && operatorType != OPERATOR_TYPE.LITERAL)
\r
1977 if (!newExp.EndsWith (" ") && !strOperator.StartsWith (" "))
\r
1978 strOperator = " " + strOperator;
\r
1979 newExp += strOperator;
\r
1980 strOperand = c.ToString ();
\r
1985 else if (c != ' ')
\r
1986 strOperator += c;
\r
1990 if (op == OP.OPERATOR)
\r
1991 throw new SyntaxErrorException (
\r
1992 "Missing operand after '" + strOperator + "' operator");
\r
1994 newExp += strOperand;
\r
2000 /// Finds and creates Expression elements.
\r
2001 /// This presumes that expression is valid.
\r
2003 protected void ParseExpression (string s)
\r
2006 // TODO/FIXME: IMHO, this should be done with different kind of parsing:
\r
2007 // char by char not operand by operand.
\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
2016 // Find parenthesis
\r
2017 if ((temp = s.IndexOf ("(")) != -1)
\r
2020 string functionName = "";
\r
2021 while (temp != 0 && s [temp - 1] != '=')
\r
2024 // Get the previous element of expression
\r
2025 while (s [temp] != '(')
\r
2027 char c = s [temp];
\r
2028 functionName = functionName + c;
\r
2032 functionName = functionName.Trim ();
\r
2033 functionName = functionName.ToLower ();
\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
2045 int startIndex = s.IndexOf ("(");
\r
2046 int i = startIndex + 1;
\r
2063 s = s.Remove (startIndex, i - startIndex);
\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
2073 else if (FindAndElement (s, ref string1, ref string2))
\r
2074 CreateAndElement (string1, string2, inside);
\r
2077 else if (FindLikeElement (s, ref string1, ref string2))
\r
2078 CreateLikeElement (string1, string2, inside);
\r
2081 else if (FindInElement (s, ref string1, ref string2))
\r
2082 CreateInElement (string1, string2, inside);
\r
2085 else if (FindEqualElement (s, ref string1, ref string2))
\r
2086 CreateEqualsElement (string1, string2, inside);
\r
2089 else if (FindUnequalElement (s, ref string1, ref string2))
\r
2090 CreateUnequalsElement (string1, string2, inside);
\r
2093 else if (FindLessThanOrEqualElement (s, ref string1, ref string2))
\r
2094 CreateLessThanOrEqualElement (string1, string2, inside);
\r
2097 else if (FindLessThanElement (s, ref string1, ref string2))
\r
2098 CreateLessThanElement (string1, string2, inside);
\r
2101 else if (FindGreaterThanOrEqualElement (s, ref string1, ref string2))
\r
2102 CreateGreaterThanOrEqualElement (string1, string2, inside);
\r
2105 else if (FindGreaterThanElement (s, ref string1, ref string2))
\r
2106 CreateGreaterThanElement (string1, string2, inside);
\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
2112 else if (FindMultiplyElement (s, ref string1, ref string2))
\r
2113 CreateMultiplyElement (string1, string2, inside);
\r
2116 else if (FindDivideElement (s, ref string1, ref string2))
\r
2117 CreateDivideElement (string1, string2, inside);
\r
2121 else if (FindAdditionElement (s, ref string1, ref string2))
\r
2122 CreateAdditionElement (string1, string2, inside);
\r
2125 else if (FindSubtractElement (s, ref string1, ref string2))
\r
2126 CreateSubtractionElement (string1, string2, inside);
\r
2129 else if (FindModulusElement (s, ref string1, ref string2))
\r
2130 CreateModulusElement (string1, string2, inside);
\r
2133 else if (FindAggregateElement (s, AGGREGATE.SUM))
\r
2134 Elements.Add (new ExpressionSum (s.Trim ()));
\r
2137 else if (FindAggregateElement (s, AGGREGATE.AVG))
\r
2138 Elements.Add (new ExpressionAvg (s.Trim ()));
\r
2141 else if (FindAggregateElement (s, AGGREGATE.MIN))
\r
2142 Elements.Add (new ExpressionMin (s.Trim ()));
\r
2145 else if (FindAggregateElement (s, AGGREGATE.MAX))
\r
2146 Elements.Add (new ExpressionMax (s.Trim ()));
\r
2149 else if (FindAggregateElement (s, AGGREGATE.COUNT))
\r
2150 Elements.Add (new ExpressionCount (s.Trim ()));
\r
2153 else if (FindAggregateElement (s, AGGREGATE.STDEV))
\r
2154 Elements.Add (new ExpressionStdev (s.Trim ()));
\r
2157 else if (FindAggregateElement (s, AGGREGATE.VAR))
\r
2158 Elements.Add (new ExpressionVar (s.Trim ()));
\r
2161 else if (FindLenElement (s))
\r
2162 Elements.Add (new ExpressionLen (s.Trim ()));
\r
2165 else if (FindIifElement (s))
\r
2166 Elements.Add (new ExpressionIif (s.Trim ()));
\r
2169 else if (FindIsNullElement (s))
\r
2170 Elements.Add (new ExpressionIsNull (s.Trim ()));
\r
2173 else if (FindSubstringElement (s))
\r
2174 Elements.Add (new ExpressionSubstring (s.Trim ()));
\r
2176 // if expression is like '(something someoperator something)'
\r
2177 else if (inside.Trim () != string.Empty)
\r
2178 ParseExpression (inside);
\r
2180 // At least, if it wasnt any of the above it is just normat string or int
\r
2183 Elements.Add (new ExpressionSingleElement (s.Trim ()));
\r
2186 #region CheckElement methods
\r
2189 // These methods are temporary for now
\r
2192 private bool FindOrElement (string s, ref string s1, ref string s2)
\r
2194 string stemp = s.ToLower ();
\r
2195 int indexOf = stemp.IndexOf("or");
\r
2197 if (indexOf == -1)
\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
2205 oldIndex = indexOf;
\r
2207 // check is the 'or' element part of string element
\r
2208 if (IsPartOfStringElement (stemp, indexOf))
\r
2211 // Check is or part of something else for example column name
\r
2212 if (indexOf != 0)
\r
2215 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
2219 if (indexOf < s.Length + 2)
\r
2222 if (stemp [indexOf + 2] != ' ' && stemp [indexOf + 2] != '\'')
\r
2226 if (IsPartOfFunction (stemp, indexOf))
\r
2229 s1 = s.Substring (0, indexOf).Trim ();
\r
2230 s2 = s.Substring (indexOf + 2).Trim ();
\r
2238 private bool FindAndElement (string s, ref string s1, ref string s2)
\r
2240 string stemp = s.ToLower ();
\r
2241 int indexOf = stemp.IndexOf("and");
\r
2243 if (indexOf == -1)
\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
2251 oldIndex = indexOf;
\r
2253 // check is the 'and' element part of string element
\r
2254 if (IsPartOfStringElement (stemp, indexOf))
\r
2258 // Check is or part of something else for example column name
\r
2259 if (indexOf != 0)
\r
2262 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
2266 if (indexOf < stemp.Length + 3)
\r
2269 if (stemp [indexOf + 3] != ' ' && stemp [indexOf + 3] != '\'')
\r
2273 if (IsPartOfFunction (stemp, indexOf))
\r
2277 s1 = s.Substring (0, indexOf).Trim ();
\r
2278 s2 = s.Substring (indexOf + 3).Trim ();
\r
2285 private bool FindLikeElement (string s, ref string s1, ref string s2)
\r
2287 string stemp = s.ToLower ();
\r
2288 int indexOf = stemp.IndexOf("like");
\r
2290 if (indexOf == -1)
\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
2298 oldIndex = indexOf;
\r
2300 // check is the 'and' element part of string element
\r
2301 if (IsPartOfStringElement (stemp, indexOf))
\r
2305 // Check is or part of something else for example column name
\r
2306 if (indexOf != 0)
\r
2309 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
2313 if (indexOf < stemp.Length + 4)
\r
2316 if (stemp [indexOf + 4] != ' ' && stemp [indexOf + 4] != '\'')
\r
2320 if (IsPartOfFunction (stemp, indexOf))
\r
2324 s1 = s.Substring (0, indexOf).Trim ();
\r
2325 s2 = s.Substring (indexOf + 4).Trim ();
\r
2332 private bool FindEqualElement (string s, ref string s1, ref string s2)
\r
2334 string stemp = s.ToLower ();
\r
2335 int indexOf = stemp.IndexOf ("=");
\r
2337 if (indexOf == -1)
\r
2340 int oldIndex = -1;
\r
2342 while ((indexOf = stemp.IndexOf ("=", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2345 oldIndex = indexOf;
\r
2347 // Check is the = part of <= or >=
\r
2348 if (stemp [indexOf - 1] == '<' || stemp [indexOf - 1] == '>')
\r
2351 // Check is the = element part of string element
\r
2352 if (IsPartOfStringElement (stemp, indexOf))
\r
2355 // Check is or part of column name
\r
2356 if (IsPartOfColumnName (stemp, indexOf))
\r
2359 if (IsPartOfFunction (stemp, indexOf))
\r
2362 s1 = s.Substring (0, indexOf).Trim ();
\r
2363 s2 = s.Substring (indexOf + 1).Trim ();
\r
2371 private bool FindUnequalElement (string s, ref string s1, ref string s2)
\r
2373 string stemp = s.ToLower ();
\r
2374 int indexOf = stemp.IndexOf ("<>");
\r
2376 if (stemp.IndexOf ("<>") == -1)
\r
2379 int oldIndex = -1;
\r
2380 while ((indexOf = stemp.IndexOf ("<>", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2383 oldIndex = indexOf;
\r
2385 // test if next charachter is something else than ' '
\r
2386 bool failed = false;
\r
2388 // Check is the <> element part of string element
\r
2389 if (IsPartOfStringElement (stemp, indexOf))
\r
2392 // Check is or part of column name
\r
2393 if (IsPartOfColumnName (stemp, indexOf))
\r
2396 if (IsPartOfFunction (stemp, indexOf))
\r
2399 s1 = s.Substring (0, indexOf).Trim ();
\r
2400 s2 = s.Substring (indexOf + 2).Trim ();
\r
2410 private bool FindLessThanElement (string s, ref string s1, ref string s2)
\r
2412 string stemp = s.ToLower ();
\r
2413 int indexOf = stemp.IndexOf ("<");
\r
2415 if (indexOf == -1)
\r
2418 int oldIndex = -1;
\r
2419 while ((indexOf = stemp.IndexOf ("<", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2422 oldIndex = indexOf;
\r
2424 // if < is part of <> or <=
\r
2425 if (stemp [indexOf + 1] == '>' || stemp [indexOf + 1] == '=')
\r
2428 // Test is < element part of string element
\r
2429 if (IsPartOfStringElement (stemp, indexOf))
\r
2432 // Check is or part of column name
\r
2433 if (IsPartOfColumnName (stemp, indexOf))
\r
2436 if (IsPartOfFunction (stemp, indexOf))
\r
2439 s1 = s.Substring (0, indexOf).Trim ();
\r
2440 s2 = s.Substring (indexOf + 1).Trim ();
\r
2448 private bool FindLessThanOrEqualElement (string s, ref string s1, ref string s2)
\r
2450 string stemp = s.ToLower ();
\r
2451 int indexOf = stemp.IndexOf ("<=");
\r
2453 if (indexOf == -1)
\r
2456 int oldIndex = -1;
\r
2457 while ((indexOf = stemp.IndexOf ("<=", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2460 oldIndex = indexOf;
\r
2461 // Test is <= element part of string element
\r
2462 if (IsPartOfStringElement (stemp, indexOf))
\r
2465 // Check is or part of column name
\r
2466 if (IsPartOfColumnName (stemp, indexOf))
\r
2469 if (IsPartOfFunction (stemp, indexOf))
\r
2472 s1 = s.Substring (0, indexOf).Trim ();
\r
2473 s2 = s.Substring (indexOf + 2).Trim ();
\r
2481 private bool FindGreaterThanElement (string s, ref string s1, ref string s2)
\r
2483 string stemp = s.ToLower ();
\r
2484 int indexOf = stemp.IndexOf (">");
\r
2486 if (indexOf == -1)
\r
2489 int oldIndex = -1;
\r
2490 while ((indexOf = stemp.IndexOf (">", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2493 oldIndex = indexOf;
\r
2495 // if < is part of <> or <=
\r
2496 if (stemp [indexOf - 1] == '<' || stemp [indexOf + 1] == '=')
\r
2499 // Test is < element part of string element
\r
2500 if (IsPartOfStringElement (stemp, indexOf))
\r
2503 // Check is or part of column name
\r
2504 if (IsPartOfColumnName (stemp, indexOf))
\r
2507 if (IsPartOfFunction (stemp, indexOf))
\r
2510 s1 = s.Substring (0, indexOf).Trim ();
\r
2511 s2 = s.Substring (indexOf + 1).Trim ();
\r
2518 private bool FindGreaterThanOrEqualElement (string s, ref string s1, ref string s2)
\r
2520 string stemp = s.ToLower ();
\r
2521 int indexOf = stemp.IndexOf (">=");
\r
2523 if (indexOf == -1)
\r
2526 int oldIndex = -1;
\r
2527 while ((indexOf = stemp.IndexOf (">=", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2530 oldIndex = indexOf;
\r
2531 bool failed = false;
\r
2532 // Test is <= element part of string element
\r
2534 // Check is or part of column name
\r
2535 if (IsPartOfColumnName (stemp, indexOf))
\r
2538 // is the element part of string element
\r
2539 if (IsPartOfStringElement (stemp, indexOf))
\r
2542 if (IsPartOfFunction (stemp, indexOf))
\r
2545 s1 = s.Substring (0, indexOf).Trim ();
\r
2546 s2 = s.Substring (indexOf + 2).Trim ();
\r
2554 private bool FindAdditionElement (string s, ref string s1, ref string s2)
\r
2556 string stemp = s.ToLower ();
\r
2557 int indexOf = stemp.IndexOf ("+");
\r
2559 if (indexOf == -1)
\r
2562 int oldIndex = -1;
\r
2563 while ((indexOf = stemp.IndexOf ("+", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2566 // FIXME: if '+' represents sign of integer
\r
2568 oldIndex = indexOf;
\r
2569 bool failed = false;
\r
2571 // Check is or part of column name
\r
2572 if (IsPartOfColumnName (stemp, indexOf))
\r
2575 // is the element part of string element
\r
2576 if (IsPartOfStringElement (stemp, indexOf))
\r
2579 if (IsPartOfFunction (stemp, indexOf))
\r
2582 s1 = s.Substring (0, indexOf).Trim ();
\r
2583 s2 = s.Substring (indexOf + 1).Trim ();
\r
2591 private bool FindSubtractElement (string s, ref string s1, ref string s2)
\r
2593 string stemp = s.ToLower ();
\r
2594 int indexOf = stemp.IndexOf ("-");
\r
2596 if (indexOf == -1)
\r
2599 int oldIndex = -1;
\r
2600 while ((indexOf = stemp.IndexOf ("-", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2603 oldIndex = indexOf;
\r
2604 bool failed = false;
\r
2606 // check is this lonely element
\r
2608 for (int i = indexOf - 1; i >= 0; i--)
\r
2610 if (stemp [i] != ' ')
\r
2620 // Check is or part of column name
\r
2621 if (IsPartOfColumnName (stemp, indexOf))
\r
2624 // is the element part of string element
\r
2625 if (IsPartOfStringElement (stemp, indexOf))
\r
2628 if (IsPartOfFunction (stemp, indexOf))
\r
2631 s1 = s.Substring (0, indexOf).Trim ();
\r
2632 s2 = s.Substring (indexOf + 1).Trim ();
\r
2640 private bool FindMultiplyElement (string s, ref string s1, ref string s2)
\r
2642 string stemp = s.ToLower ();
\r
2643 int indexOf = stemp.IndexOf ("*");
\r
2645 if (indexOf == -1)
\r
2648 int oldIndex = -1;
\r
2649 while ((indexOf = stemp.IndexOf ("*", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2653 oldIndex = indexOf;
\r
2654 bool failed = false;
\r
2656 // FIXME: If there is a divide operator before multiply operator.
\r
2658 // Check is or part of column name
\r
2659 if (IsPartOfColumnName (stemp, indexOf))
\r
2662 // is the element part of string element
\r
2663 if (IsPartOfStringElement (stemp, indexOf))
\r
2666 if (IsPartOfFunction (stemp, indexOf))
\r
2669 s1 = s.Substring (0, indexOf).Trim ();
\r
2670 s2 = s.Substring (indexOf + 1).Trim ();
\r
2678 private bool FindDivideElement (string s, ref string s1, ref string s2)
\r
2680 string stemp = s.ToLower ();
\r
2681 int indexOf = stemp.IndexOf ("/");
\r
2683 if (indexOf == -1)
\r
2686 int oldIndex = -1;
\r
2687 while ((indexOf = stemp.IndexOf ("/", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2691 oldIndex = indexOf;
\r
2692 bool failed = false;
\r
2694 // FIXME: If there is a multiply operator before divide operator.
\r
2696 // Check is or part of column name
\r
2697 if (IsPartOfColumnName (stemp, indexOf))
\r
2700 // is the element part of string element
\r
2701 if (IsPartOfStringElement (stemp, indexOf))
\r
2704 if (IsPartOfFunction (stemp, indexOf))
\r
2707 s1 = s.Substring (0, indexOf).Trim ();
\r
2708 s2 = s.Substring (indexOf + 1).Trim ();
\r
2716 private bool FindModulusElement (string s, ref string s1, ref string s2)
\r
2718 string stemp = s.ToLower ();
\r
2719 int indexOf = stemp.IndexOf ("%");
\r
2721 if (indexOf == -1)
\r
2724 int oldIndex = -1;
\r
2725 while ((indexOf = stemp.IndexOf ("%", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2729 oldIndex = indexOf;
\r
2730 bool failed = false;
\r
2732 // FIXME: If there is a multiply operator before divide operator.
\r
2734 // Check is or part of column name
\r
2735 if (IsPartOfColumnName (stemp, indexOf))
\r
2738 // is the element part of string element
\r
2739 if (IsPartOfStringElement (stemp, indexOf))
\r
2742 s1 = s.Substring (0, indexOf).Trim ();
\r
2743 s2 = s.Substring (indexOf + 1).Trim ();
\r
2751 private bool FindAggregateElement (string s, AGGREGATE aggregate)
\r
2753 string agg = null;
\r
2755 switch (aggregate)
\r
2758 case AGGREGATE.SUM:
\r
2761 case AGGREGATE.AVG:
\r
2764 case AGGREGATE.MIN:
\r
2767 case AGGREGATE.MAX:
\r
2770 case AGGREGATE.COUNT:
\r
2773 case AGGREGATE.STDEV:
\r
2776 case AGGREGATE.VAR:
\r
2780 throw new NotImplementedException ();
\r
2784 string stemp = s.ToLower ();
\r
2785 int indexOf = stemp.IndexOf (agg);
\r
2787 if (indexOf == -1)
\r
2790 int oldIndex = -1;
\r
2791 while ((indexOf = stemp.IndexOf (agg, oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2794 oldIndex = indexOf;
\r
2795 bool failed = false;
\r
2797 // Check is or part of column name
\r
2798 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2801 // is the element part of string element
\r
2802 if (IsPartOfStringElement (stemp, indexOf))
\r
2813 private bool FindSumElement (string s)
\r
2815 string stemp = s.ToLower ();
\r
2816 int indexOf = stemp.IndexOf ("sum");
\r
2818 if (indexOf == -1)
\r
2821 int oldIndex = -1;
\r
2822 while ((indexOf = stemp.IndexOf ("sum", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2825 oldIndex = indexOf;
\r
2826 bool failed = false;
\r
2828 // Check is or part of column name
\r
2829 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2832 // is the element part of string element
\r
2833 if (IsPartOfStringElement (stemp, indexOf))
\r
2843 private bool FindAvgElement (string s)
\r
2845 string stemp = s.ToLower ();
\r
2846 int indexOf = stemp.IndexOf ("avg");
\r
2848 if (indexOf == -1)
\r
2851 int oldIndex = -1;
\r
2852 while ((indexOf = stemp.IndexOf ("avg", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2855 oldIndex = indexOf;
\r
2856 bool failed = false;
\r
2858 // Check is or part of column name
\r
2859 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2862 // is the element part of string element
\r
2863 if (IsPartOfStringElement (stemp, indexOf))
\r
2872 private bool FindMinElement (string s)
\r
2874 string stemp = s.ToLower ();
\r
2875 int indexOf = stemp.IndexOf ("min");
\r
2877 if (indexOf == -1)
\r
2880 int oldIndex = -1;
\r
2881 while ((indexOf = stemp.IndexOf ("min", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2884 oldIndex = indexOf;
\r
2885 bool failed = false;
\r
2887 // Check is or part of column name
\r
2888 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2891 // is the element part of string element
\r
2892 if (IsPartOfStringElement (stemp, indexOf))
\r
2901 private bool FindMaxElement (string s)
\r
2903 string stemp = s.ToLower ();
\r
2904 int indexOf = stemp.IndexOf ("max");
\r
2906 if (indexOf == -1)
\r
2909 int oldIndex = -1;
\r
2910 while ((indexOf = stemp.IndexOf ("max", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2913 oldIndex = indexOf;
\r
2914 bool failed = false;
\r
2916 // Check is or part of column name
\r
2917 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2920 // is the element part of string element
\r
2921 if (IsPartOfStringElement (stemp, indexOf))
\r
2930 private bool FindCountElement (string s)
\r
2932 string stemp = s.ToLower ();
\r
2933 int indexOf = stemp.IndexOf ("count");
\r
2935 if (indexOf == -1)
\r
2938 int oldIndex = -1;
\r
2939 while ((indexOf = stemp.IndexOf ("count", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2942 oldIndex = indexOf;
\r
2943 bool failed = false;
\r
2945 // Check is or part of column name
\r
2946 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2949 // is the element part of string element
\r
2950 if (IsPartOfStringElement (stemp, indexOf))
\r
2959 private bool FindStdevElement (string s)
\r
2961 string stemp = s.ToLower ();
\r
2962 int indexOf = stemp.IndexOf ("stdev");
\r
2964 if (indexOf == -1)
\r
2967 int oldIndex = -1;
\r
2968 while ((indexOf = stemp.IndexOf ("stdev", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2971 oldIndex = indexOf;
\r
2972 bool failed = false;
\r
2974 // Check is or part of column name
\r
2975 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2978 // is the element part of string element
\r
2979 if (IsPartOfStringElement (stemp, indexOf))
\r
2988 private bool FindVarElement (string s)
\r
2990 string stemp = s.ToLower ();
\r
2991 int indexOf = stemp.IndexOf ("var");
\r
2993 if (indexOf == -1)
\r
2996 int oldIndex = -1;
\r
2997 while ((indexOf = stemp.IndexOf ("var", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
3000 oldIndex = indexOf;
\r
3001 bool failed = false;
\r
3003 // Check is or part of column name
\r
3004 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
3007 // is the element part of string element
\r
3008 if (IsPartOfStringElement (stemp, indexOf))
\r
3017 private bool FindLenElement (string s)
\r
3019 string stemp = s.ToLower ();
\r
3020 int indexOf = stemp.IndexOf ("len");
\r
3022 if (indexOf == -1)
\r
3025 int oldIndex = -1;
\r
3026 while ((indexOf = stemp.IndexOf ("len", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
3029 oldIndex = indexOf;
\r
3030 bool failed = false;
\r
3032 // Check is or part of column name
\r
3033 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
3036 // is the element part of string element
\r
3037 if (IsPartOfStringElement (stemp, indexOf))
\r
3047 private bool FindIifElement (string s)
\r
3049 string stemp = s.ToLower ();
\r
3050 int indexOf = stemp.IndexOf ("iif");
\r
3052 if (indexOf == -1)
\r
3055 int oldIndex = -1;
\r
3056 while ((indexOf = stemp.IndexOf ("iif", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
3059 oldIndex = indexOf;
\r
3060 bool failed = false;
\r
3062 // Check is or part of column name
\r
3063 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
3066 // is the element part of string element
\r
3067 if (IsPartOfStringElement (stemp, indexOf))
\r
3076 private bool FindIsNullElement (string s)
\r
3078 string stemp = s.ToLower ();
\r
3079 int indexOf = stemp.IndexOf ("isnull");
\r
3081 if (indexOf == -1)
\r
3084 int oldIndex = -1;
\r
3085 while ((indexOf = stemp.IndexOf ("isnull", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
3088 oldIndex = indexOf;
\r
3089 bool failed = false;
\r
3091 // Check is or part of column name
\r
3092 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
3095 // is the element part of string element
\r
3096 if (IsPartOfStringElement (stemp, indexOf))
\r
3105 private bool FindSubstringElement (string s)
\r
3107 string stemp = s.ToLower ();
\r
3108 int indexOf = stemp.IndexOf ("substring");
\r
3110 if (indexOf == -1)
\r
3113 int oldIndex = -1;
\r
3114 while ((indexOf = stemp.IndexOf ("substring", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
3117 oldIndex = indexOf;
\r
3118 bool failed = false;
\r
3120 // Check is or part of column name
\r
3121 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
3124 // is the element part of string element
\r
3125 if (IsPartOfStringElement (stemp, indexOf))
\r
3134 private bool FindInElement (string s, ref string s1, ref string s2)
\r
3136 string stemp = s.ToLower ();
\r
3137 int indexOf = stemp.IndexOf ("in");
\r
3139 if (indexOf == -1)
\r
3142 int oldIndex = -1;
\r
3143 while ((indexOf = stemp.IndexOf ("in", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
3145 oldIndex = indexOf;
\r
3147 // check is the 'and' element part of string element
\r
3148 if (IsPartOfStringElement (stemp, indexOf))
\r
3152 // Check is or part of something else for example column name
\r
3153 if (indexOf != 0)
\r
3155 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
3159 if (indexOf < stemp.Length + 2)
\r
3161 if (stemp [indexOf + 2] != ' ' && stemp [indexOf + 2] != '\'')
\r
3165 if (IsPartOfFunction (stemp, indexOf))
\r
3168 s1 = s.Substring (0, indexOf).Trim ();
\r
3169 s2 = s.Substring (indexOf + 2).Trim ();
\r
3177 #endregion // CheckElement methods
\r
3179 #region CreateElement methods
\r
3182 // These methods are going to be removed when way of parsing is changed
\r
3185 private void CreateOrElement (string s1, string s2, string inside)
\r
3187 CheckParenthesis (inside, ref s1, ref s2);
\r
3188 Elements.Add (new ExpressionOr (s1.Trim (), s2.Trim ()));
\r
3191 private void CreateAndElement (string s1, string s2, string inside)
\r
3193 CheckParenthesis (inside, ref s1, ref s2);
\r
3194 Elements.Add (new ExpressionAnd (s1.Trim (), s2.Trim ()));
\r
3197 private void CreateLikeElement (string s1, string s2, string inside)
\r
3199 CheckParenthesis (inside, ref s1, ref s2);
\r
3200 Elements.Add (new ExpressionLike (s1.Trim (), s2.Trim ()));
\r
3203 private void CreateInElement (string s1, string s2, string inside)
\r
3205 CheckParenthesis (inside, ref s1, ref s2);
\r
3206 Elements.Add (new ExpressionIn (s1.Trim (), s2.Trim ()));
\r
3209 private void CreateEqualsElement (string s1, string s2, string inside)
\r
3211 CheckParenthesis (inside, ref s1, ref s2);
\r
3212 Elements.Add (new ExpressionEquals (s1.Trim (), s2.Trim ()));
\r
3215 private void CreateUnequalsElement (string s1, string s2, string inside)
\r
3217 CheckParenthesis (inside, ref s1, ref s2);
\r
3218 Elements.Add (new ExpressionUnequals (s1.Trim (), s2.Trim ()));
\r
3221 private void CreateLessThanElement (string s1, string s2, string inside)
\r
3223 CheckParenthesis (inside, ref s1, ref s2);
\r
3224 Elements.Add (new ExpressionLessThan (s1.Trim (), s2.Trim ()));
\r
3227 private void CreateLessThanOrEqualElement (string s1, string s2, string inside)
\r
3229 CheckParenthesis (inside, ref s1, ref s2);
\r
3230 Elements.Add (new ExpressionLessThanOrEqual (s1.Trim (), s2.Trim ()));
\r
3233 private void CreateGreaterThanElement (string s1, string s2, string inside)
\r
3235 CheckParenthesis (inside, ref s1, ref s2);
\r
3236 Elements.Add (new ExpressionGreaterThan (s1.Trim (), s2.Trim ()));
\r
3240 private void CreateGreaterThanOrEqualElement (string s1, string s2, string inside)
\r
3242 CheckParenthesis (inside, ref s1, ref s2);
\r
3243 Elements.Add (new ExpressionGreaterThanOrEqual (s1.Trim (), s2.Trim ()));
\r
3246 private void CreateAdditionElement (string s1, string s2, string inside)
\r
3248 CheckParenthesis (inside, ref s1, ref s2);
\r
3249 Elements.Add (new ExpressionAddition (s1.Trim (), s2.Trim ()));
\r
3252 private void CreateSubtractionElement (string s1, string s2, string inside)
\r
3254 CheckParenthesis (inside, ref s1, ref s2);
\r
3255 Elements.Add (new ExpressionSubtraction (s1.Trim (), s2.Trim ()));
\r
3258 private void CreateMultiplyElement (string s1, string s2, string inside)
\r
3260 CheckParenthesis (inside, ref s1, ref s2);
\r
3261 Elements.Add (new ExpressionMultiply (s1.Trim (), s2.Trim ()));
\r
3264 private void CreateDivideElement (string s1, string s2, string inside)
\r
3266 CheckParenthesis (inside, ref s1, ref s2);
\r
3267 Elements.Add (new ExpressionDivide (s1.Trim (), s2.Trim ()));
\r
3270 private void CreateModulusElement (string s1, string s2, string inside)
\r
3272 CheckParenthesis (inside, ref s1, ref s2);
\r
3273 Elements.Add (new ExpressionModulus (s1.Trim (), s2.Trim ()));
\r
3276 #endregion // CreateElemnt methods
\r
3278 #region Little helppers
\r
3280 private void CheckParenthesis (string inside, ref string s1, ref string s2)
\r
3282 if (s1 == string.Empty && inside != string.Empty)
\r
3284 else if (s2 == string.Empty && inside != string.Empty)
\r
3290 /// Checks is the element part of stringelement
\r
3292 private bool IsPartOfStringElement (string s, int indexOf)
\r
3294 // count how many '-charachters are before or. If count is odd it means or IS between quotes
\r
3296 for (int i = indexOf - 1; i >= 0; i--)
\r
3298 if (s [i] == '\'')
\r
3302 if (quotes % 2 != 0)
\r
3309 /// Checks is the element part of column table
\r
3311 private bool IsPartOfColumnName (string s, int indexOf)
\r
3313 for (int i = indexOf; i >= 0; i--)
\r
3316 // If the element is between [] it is part of columnname
\r
3317 if (s [i] == '\'' || s [i] == ']')
\r
3321 else if (s [i] == '[')
\r
3332 /// Checks are element part of function
\r
3334 private bool IsPartOfFunction (string s, int indexOf)
\r
3338 // If ',' or '\'' comes before '(' this element is not part of function's parameters
\r
3341 for (int i = indexOf; i >= 0; i--)
\r
3344 if (s [i] == '(' || s [i] == ',')
\r
3348 else if (s [i] == ')')
\r
3357 #endregion // Little helppers
\r