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 enum OP {OPERATOR, OPERAND};
\r
31 enum OPERATOR_TYPE {SYMBOLIC, LITERAL, UNDEFINED};
\r
32 enum OPERAND_TYPE {NUMERIC, STRING, UNDEFINED};
\r
34 #endregion // Fields
\r
36 public ExpressionMainElement (string s)
\r
38 s = ValidateExpression (s);
\r
39 ParseExpression (s);
\r
42 public override bool Test (DataRow Row) {
\r
44 foreach (ExpressionElement El in Elements) {
\r
53 /// Checks syntax of expression and throws exception if needed.
\r
54 /// Also removes whitespaces between operator elements for example: age < = 64 --> age <= 64
\r
56 private string ValidateExpression (string s)
\r
59 // TODO: find out nice way to do this. This is NOT nice way :-P
\r
63 OPERATOR_TYPE operatorType = OPERATOR_TYPE.UNDEFINED;
\r
65 string strOperator = "";
\r
66 string strOperand = "";
\r
68 int parentheses = 0;
\r
70 bool isDigit = false;
\r
71 bool litOperator = false;
\r
73 for (int i = 0; i < s.Length; i++) {
\r
80 if ((c == '\n' || c == '\t') && quotes == 0)
\r
83 if (op == OP.OPERAND && c == '(')
\r
85 else if (op == OP.OPERAND && c == ')')
\r
88 if (c == ' ' && op == OP.OPERAND && (quotes % 2) == 0 && parentheses == 0) {
\r
91 newExp += strOperand;
\r
96 if (op == OP.OPERAND) {
\r
98 if (!Char.IsDigit (c) && isDigit && (quotes % 2) == 0) {
\r
100 newExp += strOperand;
\r
103 operatorType = OPERATOR_TYPE.UNDEFINED;
\r
109 if (op == OP.OPERATOR) {
\r
112 if (operatorType == OPERATOR_TYPE.UNDEFINED) {
\r
114 if (c == '<' || c == '=' || c == '>' || c == '*' || c == '/' || c == '%'
\r
115 || c == '-' || c == '+')
\r
117 operatorType = OPERATOR_TYPE.SYMBOLIC;
\r
119 operatorType = OPERATOR_TYPE.LITERAL;
\r
121 else if (operatorType == OPERATOR_TYPE.SYMBOLIC) {
\r
123 if (c != '<' && c != '=' && c != '>' && c != ' ') {
\r
125 // this is COPY-PASTE
\r
127 if (!newExp.EndsWith (" ") && !strOperator.StartsWith (" "))
\r
128 strOperator = " " + strOperator;
\r
130 newExp += strOperator;
\r
132 if (Char.IsDigit (c))
\r
135 strOperand = c.ToString ();
\r
142 if (operatorType == OPERATOR_TYPE.LITERAL && c == ' ') {
\r
144 newExp += strOperator;
\r
150 if (Char.IsDigit (c) && operatorType != OPERATOR_TYPE.LITERAL) {
\r
154 if (!newExp.EndsWith (" ") && !strOperator.StartsWith (" "))
\r
155 strOperator = " " + strOperator;
\r
156 newExp += strOperator;
\r
157 strOperand = c.ToString ();
\r
167 if (op == OP.OPERATOR)
\r
168 throw new SyntaxErrorException (
\r
169 "Missing operand after '" + strOperator + "' operator");
\r
171 newExp += strOperand;
\r
178 // O_P_E_R_A_T_O_R_S
\r
184 internal class ExpressionEquals : ExpressionElement
\r
187 public ExpressionEquals (string exp1, string exp2)
\r
191 ParseExpression (exp1);
\r
192 ParseExpression (exp2);
\r
195 public override bool Test (DataRow Row) {
\r
197 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
198 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
200 return ExpressionElement.Compare (E1, E2, Row) == 0;
\r
207 internal class ExpressionLessThan : ExpressionElement
\r
210 public ExpressionLessThan (string exp1, string exp2)
\r
214 ParseExpression (exp1);
\r
215 ParseExpression (exp2);
\r
218 public override bool Test (DataRow Row) {
\r
220 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
221 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
223 return ExpressionElement.Compare (E1, E2, Row) < 0;
\r
230 internal class ExpressionLessThanOrEqual : ExpressionElement
\r
233 public ExpressionLessThanOrEqual (string exp1, string exp2)
\r
237 ParseExpression (exp1);
\r
238 ParseExpression (exp2);
\r
241 public override bool Test (DataRow Row) {
\r
243 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
244 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
246 return ExpressionElement.Compare (E1, E2, Row) <= 0;
\r
253 internal class ExpressionGreaterThan : ExpressionElement
\r
256 public ExpressionGreaterThan (string exp1, string exp2)
\r
260 ParseExpression (exp1);
\r
261 ParseExpression (exp2);
\r
264 public override bool Test (DataRow Row) {
\r
266 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
267 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
269 return ExpressionElement.Compare (E1, E2, Row) > 0;
\r
276 internal class ExpressionGreaterThanOrEqual : ExpressionElement
\r
279 public ExpressionGreaterThanOrEqual (string exp1, string exp2)
\r
283 ParseExpression (exp1);
\r
284 ParseExpression (exp2);
\r
287 public override bool Test (DataRow Row) {
\r
289 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
290 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
292 return ExpressionElement.Compare (E1, E2, Row) >= 0;
\r
299 internal class ExpressionUnequals : ExpressionElement
\r
302 public ExpressionUnequals (string exp1, string exp2)
\r
306 ParseExpression (exp1);
\r
307 ParseExpression (exp2);
\r
310 public override bool Test (DataRow Row) {
\r
312 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
313 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
315 return ExpressionElement.Compare (E1, E2, Row) != 0;
\r
321 /// Class for LIKE-operator
\r
323 internal class ExpressionLike : ExpressionElement
\r
326 public ExpressionLike (string exp1, string exp2)
\r
328 ParseExpression (exp1);
\r
329 ParseExpression (exp2);
\r
332 public override bool Test (DataRow Row) {
\r
334 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
335 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
336 object value1 = E1.Result (Row);
\r
337 object value2 = E2.Result (Row);
\r
339 if (value1.GetType () != typeof (string) || value2.GetType () != typeof (string))
\r
340 throw new Exception (); // TODO: what exception
\r
342 string operand1 = value1.ToString ();
\r
343 string operand2 = value2.ToString ();
\r
345 // find out is there wildcards like * or %.
\r
346 while (operand2.EndsWith ("*") || operand2.EndsWith ("%"))
\r
347 operand2 = operand2.Remove (operand2.Length - 1, 1);
\r
348 while (operand2.StartsWith ("*") || operand2.StartsWith ("%"))
\r
349 operand2 = operand2.Remove (0, 1);
\r
354 indexOf = operand2.IndexOf ("*");
\r
355 while (indexOf != -1) {
\r
357 oldIndex = indexOf + 1;
\r
358 if (operand2 [indexOf + 1] != ']' || operand2 [indexOf - 1] != '[')
\r
359 throw new EvaluateException ("Error in Like operator: ther string pattern " + operand1 + " is invalid");
\r
361 operand2 = operand2.Remove (indexOf + 1, 1);
\r
362 operand2 = operand2.Remove (indexOf -1, 1);
\r
366 indexOf = operand2.IndexOf ("*", oldIndex);
\r
370 indexOf = operand2.IndexOf ("%");
\r
371 while (indexOf != -1) {
\r
373 oldIndex = indexOf + 1;
\r
375 if (operand2 [indexOf + 1] != ']' || operand2 [indexOf - 1] != '[')
\r
376 throw new EvaluateException ("Error in Like operator: ther string pattern " + operand2 + " is invalid");
\r
378 operand2 = operand2.Remove (indexOf + 1, 1);
\r
379 operand2 = operand2.Remove (indexOf -1, 1);
\r
383 indexOf = operand2.IndexOf ("%", oldIndex);
\r
386 int len2 = operand2.Length;
\r
387 int startIndex = 0;
\r
388 while ((startIndex + len2) <= operand1.Length) {
\r
389 if (String.Compare (operand1.Substring (0, len2), operand2, !Row.Table.CaseSensitive) == 0)
\r
402 internal class ExpressionOr : ExpressionElement
\r
404 public ExpressionOr (string exp1, string exp2)
\r
406 ParseExpression (exp1);
\r
407 ParseExpression (exp2);
\r
410 public override bool Test (DataRow Row)
\r
412 foreach (ExpressionElement El in Elements) {
\r
424 internal class ExpressionAnd : ExpressionElement
\r
426 public ExpressionAnd (string exp1, string exp2)
\r
428 ParseExpression (exp1);
\r
429 ParseExpression (exp2);
\r
432 public override object Result (DataRow Row) {
\r
437 public override bool Test (DataRow Row)
\r
439 foreach (ExpressionElement El in Elements) {
\r
440 if (!El.Test (Row))
\r
450 // A_R_I_T_H_M_E_T_I_C O_P_E_R_A_T_O_R_S
\r
456 internal class ExpressionAddition : ExpressionElement
\r
458 public ExpressionAddition (string exp1, string exp2)
\r
462 ParseExpression (exp1);
\r
463 ParseExpression (exp2);
\r
466 public override Type ResultType (DataRow Row)
\r
468 Type ResultType = typeof (string);
\r
469 ExpressionElement exp1Temp = ((ExpressionElement)Elements [0]);
\r
470 ExpressionElement exp2Temp = ((ExpressionElement)Elements [1]);
\r
472 if (exp1Temp.ResultType (Row) == typeof (string) || exp2Temp.ResultType (Row) == typeof (string))
\r
473 ResultType = typeof (string);
\r
475 else if (exp1Temp.ResultType (Row) == typeof (long) || exp2Temp.ResultType (Row) == typeof (long))
\r
476 ResultType = typeof (long);
\r
478 else if (exp1Temp.ResultType (Row) == typeof (int) || exp2Temp.ResultType (Row) == typeof (int))
\r
479 ResultType = typeof (int);
\r
484 public override object Result (DataRow Row)
\r
486 return CalculateResult (Row);
\r
489 protected override object Calculate (object value1, object value2, Type TempType)
\r
491 object Result = null;
\r
493 if (TempType == typeof (string))
\r
494 Result = (string)value1 + (string)value2;
\r
495 else if (TempType == typeof (long))
\r
496 Result = (long)value1 + (long)value2;
\r
497 else if (TempType == typeof (int))
\r
498 Result = (int)value1 + (int)value2;
\r
499 else if (TempType == typeof (short))
\r
500 Result = (short)value1 + (short)value2;
\r
501 else if (TempType == typeof (ulong))
\r
502 Result = (ulong)value1 + (ulong)value2;
\r
503 else if (TempType == typeof (uint))
\r
504 Result = (uint)value1 + (uint)value2;
\r
505 else if (TempType == typeof (ushort))
\r
506 Result = (ushort)value1 + (ushort)value2;
\r
507 else if (TempType == typeof (byte))
\r
508 Result = (byte)value1 + (byte)value2;
\r
509 else if (TempType == typeof (sbyte))
\r
510 Result = (sbyte)value1 + (sbyte)value2;
\r
512 //else if (TempType == typeof (bool))
\r
513 // Result = (bool)value1 + (bool)value2;
\r
514 else if (TempType == typeof (float))
\r
515 Result = (float)value1 + (float)value2;
\r
516 else if (TempType == typeof (double))
\r
517 Result = (double)value1 + (double)value2;
\r
518 else if (TempType == typeof (decimal))
\r
519 Result = (decimal)value1 + (decimal)value2;
\r
521 //else if (TempType == typeof (DateTime))
\r
522 // Result = (DateTime)value1 + (DateTime)value2;
\r
528 // This method is shouldnt never invoked
\r
529 public override bool Test (DataRow Row)
\r
531 throw new EvaluateException ();
\r
538 internal class ExpressionSubtraction : ExpressionElement
\r
540 public ExpressionSubtraction (string exp1, string exp2)
\r
544 ParseExpression (exp1);
\r
545 ParseExpression (exp2);
\r
548 public override object Result (DataRow Row)
\r
550 return CalculateResult (Row);
\r
553 // This method is shouldnt never invoked
\r
554 public override bool Test (DataRow Row)
\r
556 throw new EvaluateException ();
\r
559 protected override object Calculate (object value1, object value2, Type TempType)
\r
561 object Result = null;
\r
564 //if (TempType == typeof (string))
\r
565 // Result = (string)value1 - (string)value2;
\r
566 if (TempType == typeof (long))
\r
567 Result = (long)value1 - (long)value2;
\r
568 else if (TempType == typeof (int))
\r
569 Result = (int)value1 - (int)value2;
\r
570 else if (TempType == typeof (short))
\r
571 Result = (short)value1 - (short)value2;
\r
572 else if (TempType == typeof (ulong))
\r
573 Result = (ulong)value1 + (ulong)value2;
\r
574 else if (TempType == typeof (uint))
\r
575 Result = (uint)value1 - (uint)value2;
\r
576 else if (TempType == typeof (ushort))
\r
577 Result = (ushort)value1 - (ushort)value2;
\r
578 else if (TempType == typeof (byte))
\r
579 Result = (byte)value1 - (byte)value2;
\r
580 else if (TempType == typeof (sbyte))
\r
581 Result = (sbyte)value1 - (sbyte)value2;
\r
583 //else if (TempType == typeof (bool))
\r
584 // Result = (bool)value1 - (bool)value2;
\r
585 else if (TempType == typeof (float))
\r
586 Result = (float)value1 - (float)value2;
\r
587 else if (TempType == typeof (double))
\r
588 Result = (double)value1 - (double)value2;
\r
589 else if (TempType == typeof (decimal))
\r
590 Result = (decimal)value1 - (decimal)value2;
\r
592 //else if (TempType == typeof (DateTime))
\r
593 // Result = (DateTime)value1 - (DateTime)value2;
\r
602 internal class ExpressionMultiply : ExpressionElement
\r
604 public ExpressionMultiply (string exp1, string exp2)
\r
608 ParseExpression (exp1);
\r
609 ParseExpression (exp2);
\r
612 public override Type ResultType (DataRow Row)
\r
614 Type ResultType = null;
\r
615 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
616 ExpressionElement E2 = ((ExpressionElement)Elements [1]);
\r
617 Type t1 = E1.ResultType (Row);
\r
618 Type t2 = E2.ResultType (Row);
\r
620 if (t1 == typeof (string) || t2 == typeof (string))
\r
621 throw new EvaluateException ("Cannon perform '*' operation on " + t1.ToString () +
\r
622 " and " + t2.ToString ());
\r
624 else if (t1 == typeof (long) || t2 == typeof (long))
\r
625 ResultType = typeof (long);
\r
627 else if (t1 == typeof (int) || t2 == typeof (int))
\r
628 ResultType = typeof (int);
\r
633 public override object Result (DataRow Row)
\r
635 return CalculateResult (Row);
\r
638 public override bool Test (DataRow Row)
\r
640 throw new EvaluateException ();
\r
643 protected override object Calculate (object value1, object value2, Type TempType)
\r
645 object Result = null;
\r
647 if (TempType == typeof (long))
\r
648 Result = (long)value1 * (long)value2;
\r
649 else if (TempType == typeof (int))
\r
650 Result = (int)value1 * (int)value2;
\r
651 else if (TempType == typeof (short))
\r
652 Result = (short)value1 * (short)value2;
\r
653 else if (TempType == typeof (ulong))
\r
654 Result = (ulong)value1 * (ulong)value2;
\r
655 else if (TempType == typeof (uint))
\r
656 Result = (uint)value1 * (uint)value2;
\r
657 else if (TempType == typeof (ushort))
\r
658 Result = (ushort)value1 * (ushort)value2;
\r
659 else if (TempType == typeof (byte))
\r
660 Result = (byte)value1 * (byte)value2;
\r
661 else if (TempType == typeof (sbyte))
\r
662 Result = (sbyte)value1 * (sbyte)value2;
\r
664 //else if (TempType == typeof (bool))
\r
665 // Result = (bool)value1 * (bool)value2;
\r
666 else if (TempType == typeof (float))
\r
667 Result = (float)value1 * (float)value2;
\r
668 else if (TempType == typeof (double))
\r
669 Result = (double)value1 * (double)value2;
\r
670 else if (TempType == typeof (decimal))
\r
671 Result = (decimal)value1 * (decimal)value2;
\r
673 //else if (TempType == typeof (DateTime))
\r
674 // Result = (DateTime)value1 * (DateTime)value2;
\r
684 internal class ExpressionDivide : ExpressionElement
\r
686 public ExpressionDivide (string exp1, string exp2)
\r
690 ParseExpression (exp1);
\r
691 ParseExpression (exp2);
\r
694 public override object Result (DataRow Row)
\r
696 return CalculateResult (Row);
\r
699 // This method is shouldnt never invoked
\r
700 public override bool Test (DataRow Row)
\r
702 throw new EvaluateException ();
\r
705 protected override object Calculate (object value1, object value2, Type TempType)
\r
707 object Result = null;
\r
709 if (TempType == typeof (long))
\r
710 Result = (long)value1 / (long)value2;
\r
712 //else if (TempType == typeof (int))
\r
713 // Result = (string)value1 / (string)value2;
\r
714 else if (TempType == typeof (int))
\r
715 Result = (int)value1 / (int)value2;
\r
716 else if (TempType == typeof (short))
\r
717 Result = (short)value1 / (short)value2;
\r
718 else if (TempType == typeof (ulong))
\r
719 Result = (ulong)value1 / (ulong)value2;
\r
720 else if (TempType == typeof (uint))
\r
721 Result = (uint)value1 / (uint)value2;
\r
722 else if (TempType == typeof (ushort))
\r
723 Result = (ushort)value1 / (ushort)value2;
\r
724 else if (TempType == typeof (byte))
\r
725 Result = (byte)value1 / (byte)value2;
\r
726 else if (TempType == typeof (sbyte))
\r
727 Result = (sbyte)value1 / (sbyte)value2;
\r
729 //else if (TempType == typeof (bool))
\r
730 // Result = (bool)value1 // (bool)value2;
\r
731 else if (TempType == typeof (float))
\r
732 Result = (float)value1 / (float)value2;
\r
733 else if (TempType == typeof (double))
\r
734 Result = (double)value1 / (double)value2;
\r
735 else if (TempType == typeof (decimal))
\r
736 Result = (decimal)value1 / (decimal)value2;
\r
738 //else if (TempType == typeof (DateTime))
\r
739 // Result = (DateTime)value1 / (DateTime)value2;
\r
748 internal class ExpressionModulus : ExpressionElement
\r
750 public ExpressionModulus (string exp1, string exp2)
\r
754 ParseExpression (exp1);
\r
755 ParseExpression (exp2);
\r
758 public override object Result (DataRow Row)
\r
760 return CalculateResult (Row);
\r
763 // This method is shouldnt never invoked
\r
764 public override bool Test (DataRow Row)
\r
766 throw new EvaluateException ();
\r
769 protected override object Calculate (object value1, object value2, Type TempType)
\r
771 object Result = null;
\r
773 if (TempType == typeof (long))
\r
774 Result = (long)value1 % (long)value2;
\r
776 //else if (TempType == typeof (int))
\r
777 // Result = (string)value1 % (string)value2;
\r
778 else if (TempType == typeof (int))
\r
779 Result = (int)value1 % (int)value2;
\r
780 else if (TempType == typeof (short))
\r
781 Result = (short)value1 % (short)value2;
\r
782 else if (TempType == typeof (ulong))
\r
783 Result = (ulong)value1 % (ulong)value2;
\r
784 else if (TempType == typeof (uint))
\r
785 Result = (uint)value1 % (uint)value2;
\r
786 else if (TempType == typeof (ushort))
\r
787 Result = (ushort)value1 % (ushort)value2;
\r
788 else if (TempType == typeof (byte))
\r
789 Result = (byte)value1 % (byte)value2;
\r
790 else if (TempType == typeof (sbyte))
\r
791 Result = (sbyte)value1 % (sbyte)value2;
\r
793 //else if (TempType == typeof (bool))
\r
794 // Result = (bool)value1 // (bool)value2;
\r
795 else if (TempType == typeof (float))
\r
796 Result = (float)value1 % (float)value2;
\r
797 else if (TempType == typeof (double))
\r
798 Result = (double)value1 % (double)value2;
\r
799 else if (TempType == typeof (decimal))
\r
800 Result = (decimal)value1 % (decimal)value2;
\r
802 //else if (TempType == typeof (DateTime))
\r
803 // Result = (DateTime)value1 / (DateTime)value2;
\r
810 // _____A_G_G_R_E_G_A_T_E_S_____
\r
813 internal class ExpressionAggregate : ExpressionElement
\r
815 //public override object Result (DataRow Row)
\r
820 public override bool Test (DataRow Row)
\r
822 throw new EvaluateException ();
\r
825 protected virtual void ParseParameters (string s)
\r
827 string stemp = s.ToLower ();
\r
828 bool inString = false;
\r
832 while (!s.StartsWith ("("))
\r
833 s = s.Remove (0, 1);
\r
836 s = s.Remove (0, 1);
\r
838 int parentheses = 0;
\r
839 for (int i = 0; i < s.Length; i++) {
\r
842 inString = !inString;
\r
843 else if (s [i] == '(')
\r
845 else if (s [i] == ')')
\r
848 if ((s [i] == ',' || s [i] == ')') && !inString && parentheses == -1) { // Parameter changed
\r
851 p1 = s.Substring (0, i);
\r
858 throw new Exception ();
\r
860 ParseExpression (p1);
\r
866 /// Class for Sum (column_Name)
\r
868 internal class ExpressionSum : ExpressionAggregate
\r
870 public ExpressionSum (string exp1)
\r
872 ParseParameters (exp1);
\r
875 public override object Result (DataRow Row)
\r
877 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
878 object value1 = E1.Result (Row);
\r
879 Type t1 = value1.GetType ();
\r
880 object result = null;
\r
882 // This could be optimized. If E1 is single element (Not child or parent) the
\r
883 // result of Sum() aggregate is allways same
\r
885 if (E1 is ExpressionSingleElement) {
\r
887 // This should be optimized somehow
\r
888 foreach (DataRow tempRow in Row.Table.Rows) {
\r
890 // TODO: other types and exceptions
\r
891 object v = E1.Result (tempRow);
\r
894 if (v == null || v == DBNull.Value)
\r
897 if (t1 == typeof (long)) {
\r
899 result = (long)result + (long)v;
\r
901 else if (t1 == typeof (int)) {
\r
903 result = (int)result + (int)v;
\r
905 else if (t1 == typeof (short)) {
\r
907 result = (short)result + (short)v;
\r
909 else if (t1 == typeof (double)) {
\r
911 result = (double)result + (double)v;
\r
913 else if (t1 == typeof (float)) {
\r
915 result = (float)result + (float)v;
\r
918 throw new NotImplementedException ();
\r
926 // FIXME: This method is copy-paste in every Aggregate class.
\r
931 /// Class for Avg (column_Name)
\r
933 internal class ExpressionAvg : ExpressionAggregate
\r
935 public ExpressionAvg (string exp1)
\r
937 ParseParameters (exp1);
\r
941 /// This is used from ExpressionStdDev for evaluating avg.
\r
943 public ExpressionAvg (ExpressionElement E)
\r
948 public override object Result (DataRow Row)
\r
950 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
951 object value1 = E1.Result (Row);
\r
952 Type original = value1.GetType ();
\r
953 object result = null;
\r
955 if (E1 is ExpressionSingleElement) {
\r
958 // This should be optimized somehow
\r
959 foreach (DataRow tempRow in Row.Table.Rows) {
\r
961 // TODO: other types and exceptions
\r
962 object v = E1.Result (tempRow);
\r
964 if (v == null || v == DBNull.Value)
\r
969 if (result == null)
\r
972 if (t1 == typeof (long)) {
\r
973 result = (long)result + (long)v;
\r
975 else if (t1 == typeof (int)) {
\r
976 result = (int)result + (int)v;
\r
978 else if (t1 == typeof (short)) {
\r
979 result = (short)result + (short)v;
\r
981 else if (t1 == typeof (double)) {
\r
982 result = (double)result + (double)v;
\r
984 else if (t1 == typeof (float)) {
\r
985 result = (float)result + (float)v;
\r
988 throw new NotImplementedException ();
\r
993 if (t1 == typeof (long))
\r
994 result = (long)result / Row.Table.Rows.Count;
\r
995 else if (t1 == typeof (int))
\r
996 result = (int)result / Row.Table.Rows.Count;
\r
997 else if (t1 == typeof (short))
\r
998 result = (short)result / Row.Table.Rows.Count;
\r
999 else if (t1 == typeof (double))
\r
1000 result = (double)result / Row.Table.Rows.Count;
\r
1008 /// Class for Min (column_Name)
\r
1010 internal class ExpressionMin : ExpressionAggregate
\r
1012 public ExpressionMin (string exp1)
\r
1014 ParseParameters (exp1);
\r
1017 public override object Result (DataRow Row)
\r
1019 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1020 object value1 = E1.Result (Row);
\r
1021 Type original = value1.GetType ();
\r
1022 object result = null;
\r
1024 if (E1 is ExpressionSingleElement) {
\r
1027 // This should be optimized somehow
\r
1028 foreach (DataRow tempRow in Row.Table.Rows) {
\r
1030 // TODO: other types and exceptions
\r
1031 object v = E1.Result (tempRow);
\r
1033 if (v == null || v == DBNull.Value)
\r
1036 t1 = v.GetType ();
\r
1038 if (result == null)
\r
1041 object CompResult = t1.InvokeMember ("CompareTo", BindingFlags.Default |
\r
1042 BindingFlags.InvokeMethod, null,
\r
1044 new object [] {result});
\r
1046 if ((int)CompResult < 0)
\r
1057 /// Class for Max (column_Name)
\r
1059 internal class ExpressionMax : ExpressionAggregate
\r
1061 public ExpressionMax (string exp1)
\r
1063 ParseParameters (exp1);
\r
1066 public override object Result (DataRow Row)
\r
1068 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1069 object value1 = E1.Result (Row);
\r
1070 Type original = value1.GetType ();
\r
1071 object result = null;
\r
1073 if (E1 is ExpressionSingleElement) {
\r
1076 // This should be optimized somehow
\r
1077 foreach (DataRow tempRow in Row.Table.Rows) {
\r
1079 // TODO: other types and exceptions
\r
1080 object v = E1.Result (tempRow);
\r
1082 if (v == null || v == DBNull.Value)
\r
1085 t1 = v.GetType ();
\r
1087 if (result == null)
\r
1090 object CompResult = t1.InvokeMember ("CompareTo", BindingFlags.Default |
\r
1091 BindingFlags.InvokeMethod, null,
\r
1093 new object [] {result});
\r
1095 if ((int)CompResult > 0)
\r
1107 /// Class for count (column)
\r
1109 internal class ExpressionCount : ExpressionAggregate
\r
1111 public ExpressionCount (string exp1)
\r
1113 ParseParameters (exp1);
\r
1116 public override object Result (DataRow Row)
\r
1118 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1121 if (E1 is ExpressionSingleElement) {
\r
1123 // This should be optimized somehow
\r
1124 foreach (DataRow tempRow in Row.Table.Rows) {
\r
1136 /// Class for StdDev (column)
\r
1138 internal class ExpressionStdev : ExpressionAggregate
\r
1140 public ExpressionStdev (string exp1)
\r
1142 ParseParameters (exp1);
\r
1145 public override object Result (DataRow Row)
\r
1147 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1148 ExpressionAvg Avg = new ExpressionAvg (E1);
\r
1150 object tempAvg = Avg.Result (Row);
\r
1153 double result = 0;
\r
1155 if (tempAvg.GetType () == typeof (int))
\r
1156 avg = (double)(int)tempAvg;
\r
1158 if (E1 is ExpressionSingleElement) {
\r
1160 foreach (DataRow tempRow in Row.Table.Rows) {
\r
1163 // (value - avg)²
\r
1164 object v = E1.Result (tempRow);
\r
1166 if (v == null || v == DBNull.Value)
\r
1169 if (v.GetType () == typeof (long))
\r
1170 sum = avg - (long)v;
\r
1171 else if (v.GetType () == typeof (int))
\r
1172 sum = avg - (int)v;
\r
1173 else if (v.GetType () == typeof (short))
\r
1174 sum = avg - (short)v;
\r
1176 throw new NotImplementedException ();
\r
1178 result += Math.Pow (sum, 2);
\r
1181 result = result / (Row.Table.Rows.Count - 1);
\r
1182 result = Math.Sqrt (result);
\r
1190 /// Class for Var (column)
\r
1192 internal class ExpressionVar : ExpressionAggregate
\r
1194 public ExpressionVar (string exp1)
\r
1196 ParseParameters (exp1);
\r
1199 public override object Result (DataRow Row)
\r
1201 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1202 ExpressionAvg Avg = new ExpressionAvg (E1);
\r
1204 object tempAvg = Avg.Result (Row);
\r
1207 double result = 0;
\r
1209 if (tempAvg.GetType () == typeof (int))
\r
1210 avg = (double)(int)tempAvg;
\r
1212 if (E1 is ExpressionSingleElement) {
\r
1214 foreach (DataRow tempRow in Row.Table.Rows) {
\r
1217 // (value - avg)²
\r
1218 object v = E1.Result (tempRow);
\r
1220 if (v == null || v == DBNull.Value)
\r
1223 if (v.GetType () == typeof (long))
\r
1224 sum = avg - (long)v;
\r
1225 else if (v.GetType () == typeof (int))
\r
1226 sum = avg - (int)v;
\r
1227 else if (v.GetType () == typeof (short))
\r
1228 sum = avg - (short)v;
\r
1230 throw new NotImplementedException ();
\r
1232 result += Math.Pow (sum, 2);
\r
1235 result = result / (Row.Table.Rows.Count - 1);
\r
1243 // _____F_U_ N_C_T_I_O_N_S_______
\r
1247 /// Class for len (string) function
\r
1249 internal class ExpressionLen : ExpressionElement
\r
1251 public ExpressionLen (string exp1)
\r
1253 _ResultType = typeof (int);
\r
1254 ParseParameters (exp1);
\r
1257 public override object Result (DataRow Row)
\r
1259 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1260 object value1 = E1.Result (Row);
\r
1262 return value1.ToString ().Length;
\r
1265 public override bool Test (DataRow Row)
\r
1267 throw new EvaluateException ();
\r
1270 public void ParseParameters (string s)
\r
1272 string stemp = s.ToLower ();
\r
1273 bool inString = false;
\r
1277 while (!s.StartsWith ("("))
\r
1278 s = s.Remove (0, 1);
\r
1281 s = s.Remove (0, 1);
\r
1282 int parentheses = 0;
\r
1283 for (int i = 0; i < s.Length; i++) {
\r
1285 if (s [i] == '\'')
\r
1286 inString = !inString;
\r
1287 else if (s [i] == '(')
\r
1289 else if (s [i] == ')')
\r
1292 if ((s [i] == ',' || s [i] == ')') && !inString && parentheses == -1) { // Parameter changed
\r
1295 p1 = s.Substring (0, i);
\r
1302 throw new Exception ();
\r
1304 ParseExpression (p1);
\r
1309 /// Class for iif (exp1, truepart, falsepart) function
\r
1311 internal class ExpressionIif : ExpressionElement
\r
1313 public ExpressionIif (string exp)
\r
1315 ParseParameters (exp);
\r
1318 public override object Result (DataRow Row)
\r
1320 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1321 ExpressionElement E2 = ((ExpressionElement)Elements [1]);
\r
1322 ExpressionElement E3 = ((ExpressionElement)Elements [2]);
\r
1324 if (E1.Test (Row)) // expression
\r
1325 return E2.Result (Row); // truepart
\r
1327 return E3.Result (Row); // false part
\r
1330 // This method is shouldnt never invoked
\r
1331 public override bool Test (DataRow Row)
\r
1333 throw new EvaluateException ();
\r
1336 public override Type ResultType (DataRow Row)
\r
1338 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1339 ExpressionElement E2 = ((ExpressionElement)Elements [1]);
\r
1340 ExpressionElement E3 = ((ExpressionElement)Elements [2]);
\r
1342 if (E1.Test (Row)) // expression
\r
1343 return E2.Result (Row).GetType (); // truepart
\r
1345 return E3.Result (Row).GetType (); // false part
\r
1349 /// Parses expressions in parameters (exp, truepart, falsepart)
\r
1351 private void ParseParameters (string s)
\r
1353 bool inString = false;
\r
1354 string stemp = s.ToLower ();
\r
1358 s = s.Substring (stemp.IndexOf ("iif") + 3);
\r
1361 while (!s.StartsWith ("("))
\r
1362 s = s.Remove (0, 1);
\r
1365 s = s.Remove (0, 1);
\r
1366 int parentheses = 0;
\r
1367 for (int i = 0; i < s.Length; i++) {
\r
1369 if (s [i] == '\'')
\r
1370 inString = !inString;
\r
1371 else if (s [i] == '(')
\r
1373 else if (s [i] == ')')
\r
1376 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1377 (s [i] == ')' && i == (s.Length -1))) { // Parameter changed
\r
1380 p1 = s.Substring (0, i);
\r
1381 s = s.Substring (i + 1);
\r
1385 else if (p2 == null) {
\r
1386 p2 = s.Substring (0, i);
\r
1387 s = s.Substring (i + 1);
\r
1391 else if (p3 == null) {
\r
1392 p3 = s.Substring (0, i);
\r
1393 s = s.Substring (i + 1);
\r
1398 throw new Exception (); // FIXME: What exception
\r
1402 if (p1 == null || p2 == null || p3 == null)
\r
1403 throw new Exception ();
\r
1405 ParseExpression (p1);
\r
1406 ParseExpression (p2);
\r
1407 ParseExpression (p3);
\r
1412 /// Class for isnull (expression, returnvalue) function
\r
1414 internal class ExpressionIsNull : ExpressionElement
\r
1416 public ExpressionIsNull (string exp)
\r
1418 ParseParameters (exp);
\r
1421 public override object Result (DataRow Row)
\r
1423 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1424 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
1426 object R1 = E1.Result (Row);
\r
1427 object value1 = null;
\r
1428 if (R1 == null || R1 == DBNull.Value)
\r
1429 return E2.Result (Row);
\r
1434 public override Type ResultType (DataRow Row)
\r
1436 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1437 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
1439 object R1 = E1.Result (Row);
\r
1440 object value1 = null;
\r
1441 if (R1 == null || R1 == DBNull.Value)
\r
1442 return E2.Result (Row).GetType ();
\r
1444 return R1.GetType ();
\r
1448 /// IsNull function does not return boolean value, so throw exception
\r
1450 public override bool Test (DataRow Row)
\r
1452 throw new EvaluateException ();
\r
1456 /// Parses parameters of function and invoke ParseExpression methods
\r
1458 private void ParseParameters (string s)
\r
1460 bool inString = false;
\r
1461 string stemp = s.ToLower ();
\r
1465 s = s.Substring (stemp.IndexOf ("isnull") + 6);
\r
1468 while (!s.StartsWith ("("))
\r
1469 s = s.Remove (0, 1);
\r
1472 s = s.Remove (0, 1);
\r
1473 int parentheses = 0;
\r
1474 for (int i = 0; i < s.Length; i++) {
\r
1476 if (s [i] == '\'')
\r
1477 inString = !inString;
\r
1478 else if (s [i] == '(')
\r
1480 else if (s [i] == ')')
\r
1483 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1484 (s [i] == ')' && i == (s.Length -1))) { // Parameter changed
\r
1487 p1 = s.Substring (0, i);
\r
1488 s = s.Substring (i + 1);
\r
1492 else if (p2 == null) {
\r
1493 p2 = s.Substring (0, i);
\r
1494 s = s.Substring (i + 1);
\r
1499 throw new Exception (); // FIXME: What exception
\r
1503 if (p1 == null || p2 == null)
\r
1504 throw new Exception ();
\r
1506 ParseExpression (p1);
\r
1507 ParseExpression (p2);
\r
1512 /// Class for Substring (expression, start, length) function
\r
1514 internal class ExpressionSubstring : ExpressionElement
\r
1516 public ExpressionSubstring (string exp)
\r
1518 ParseParameters (exp);
\r
1519 _ResultType = typeof (string);
\r
1522 public override object Result (DataRow Row)
\r
1524 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1525 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
1526 ExpressionElement E3 = (ExpressionElement)Elements [2];
\r
1528 object value1 = E1.Result (Row);
\r
1529 object value2 = E2.Result (Row);
\r
1530 object value3 = E3.Result (Row);
\r
1531 Type t1 = value1.GetType ();
\r
1532 Type t2 = value2.GetType ();
\r
1533 Type t3 = value3.GetType ();
\r
1535 if (value1 == null || value2 == null || value3 == null
\r
1536 || value1 == DBNull.Value || value2 == DBNull.Value || value3 == DBNull.Value)
\r
1537 return string.Empty;
\r
1539 if (t1 != typeof (string))
\r
1540 throw new Exception (); // FIXME: what exception
\r
1541 else if (t2 != typeof (int))
\r
1542 throw new EvaluateException ("Type mismatch is function argument: Substring (), argument 2, excepted System.Int32");
\r
1543 else if (t3 != typeof (int))
\r
1544 throw new EvaluateException ("Type mismatch is function argument: Substring (), argument 3, excepted System.Int32");
\r
1546 string str = value1.ToString ();
\r
1547 int start = (int)value2;
\r
1548 int length = (int)value3;
\r
1550 if (str.Length < start)
\r
1551 str = string.Empty;
\r
1553 if ((start + length - 1) > str.Length)
\r
1554 str = str.Substring (start - 1);
\r
1556 str = str.Substring (start - 1, length);
\r
1563 /// IsNull function does not return boolean value, so throw exception
\r
1565 public override bool Test (DataRow Row)
\r
1567 throw new EvaluateException ();
\r
1571 /// Parses parameters of function and invoke ParseExpression methods
\r
1573 private void ParseParameters (string s)
\r
1575 bool inString = false;
\r
1576 string stemp = s.ToLower ();
\r
1581 s = s.Substring (stemp.IndexOf ("substring") + 9);
\r
1584 while (!s.StartsWith ("("))
\r
1585 s = s.Remove (0, 1);
\r
1588 s = s.Remove (0, 1);
\r
1589 int parentheses = 0;
\r
1590 for (int i = 0; i < s.Length; i++) {
\r
1592 if (s [i] == '\'')
\r
1593 inString = !inString;
\r
1594 else if (s [i] == '(')
\r
1596 else if (s [i] == ')')
\r
1600 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1601 (s [i] == ')' && i == (s.Length -1))) { // Parameter changed
\r
1604 p1 = s.Substring (0, i);
\r
1605 s = s.Substring (i + 1);
\r
1609 else if (p2 == null) {
\r
1610 p2 = s.Substring (0, i);
\r
1611 s = s.Substring (i + 1);
\r
1615 else if (p3 == null) {
\r
1616 p3 = s.Substring (0, i);
\r
1617 s = s.Substring (i + 1);
\r
1622 throw new Exception (); // FIXME: What exception
\r
1626 if (p1 == null || p2 == null)
\r
1627 throw new Exception ();
\r
1629 ParseExpression (p1);
\r
1630 ParseExpression (p2);
\r
1631 ParseExpression (p3);
\r
1636 /// Class for just one element for example string, int, ...
\r
1638 internal class ExpressionSingleElement : ExpressionElement
\r
1640 private object Element = null;
\r
1642 public ExpressionSingleElement (string s)
\r
1644 // TODO: Every type should be checked
\r
1645 if (s.StartsWith ("'") && s.EndsWith ("'")) {
\r
1646 Element = s.Substring (1, s.Length - 2);
\r
1647 _ResultType = typeof (string);
\r
1649 else if (!Char.IsDigit (s [0]) && s [0] != '-' && s [0] != '+') {
\r
1651 _ResultType = typeof (DataColumn);
\r
1654 _ResultType = typeof (int);
\r
1655 Element = int.Parse (s);
\r
1659 public override object Result (DataRow Row)
\r
1661 object Result = null;
\r
1662 if (ResultType (Row) == typeof (DataColumn)) {
\r
1664 if (!Row.Table.Columns.Contains (Element.ToString ()))
\r
1665 throw new EvaluateException ("Column name '" + Element.ToString () + "' not found.");
\r
1667 Result = Row [Element.ToString ()];
\r
1675 public override bool Test (DataRow Row)
\r
1677 throw new EvaluateException ();
\r
1682 /// Parent class of all the elements of expression
\r
1684 internal abstract class ExpressionElement
\r
1687 // TODO/FIXME: This class should be inherited more than once. I mean own subclass for operators, functions,...
\r
1690 protected string exp1;
\r
1691 protected string exp2;
\r
1692 protected Type _ResultType;
\r
1694 protected ArrayList Elements = new ArrayList ();
\r
1696 enum AGGREGATE {SUM, AVG, MIN, MAX, COUNT, STDEV, VAR}
\r
1697 //protected ArrayList Singles = new ArrayList ();
\r
1700 /// Tells does the current expressions match to current DataRow
\r
1702 abstract public bool Test (DataRow Row);
\r
1704 public virtual object Result (DataRow Row) {return null;}
\r
1706 public virtual Type ResultType (DataRow Row)
\r
1708 return _ResultType;
\r
1711 protected object CalculateResult (DataRow Row)
\r
1713 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1714 ExpressionElement E2 = ((ExpressionElement)Elements [1]);
\r
1715 object Result = null;
\r
1716 object value1 = E1.Result (Row);
\r
1717 object value2 = E2.Result (Row);
\r
1718 Type t1 = value1.GetType ();
\r
1719 Type t2 = value2.GetType ();
\r
1722 if (value1 == DBNull.Value && value2 == DBNull.Value)
\r
1725 // TODO: More types
\r
1727 if (t1 == typeof (string) || t2 == typeof (string)) {
\r
1729 if (t1 != typeof (string))
\r
1730 value1 = Convert.ChangeType (value1, Type.GetTypeCode (t2));
\r
1731 else if (t2 != typeof (string))
\r
1732 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1736 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1738 Result = Calculate (value1, value2, t1);
\r
1742 protected virtual object Calculate (object value1, object value2, Type TempType)
\r
1748 /// static method for comparing two ExpressionElement. This is used in =, <, >, <>, <=, >= elements.
\r
1749 /// If elements are equal returns 0, if E1 is less that E2, return -1 else if E1 is greater 1
\r
1751 protected static int Compare (ExpressionElement E1, ExpressionElement E2, DataRow Row)
\r
1753 int ReturnValue = 0;
\r
1755 object value1 = E1.Result (Row);
\r
1756 object value2 = E2.Result (Row);
\r
1758 if ((value1 == null || value1 == DBNull.Value) && (value2 == null || value2 == DBNull.Value))
\r
1760 else if (value2 == null || value2 == DBNull.Value)
\r
1762 else if (value1 == null || value1 == DBNull.Value)
\r
1765 Type t1 = value1.GetType ();
\r
1766 Type t2 = value2.GetType ();
\r
1768 Type RT1 = E1.ResultType (Row);
\r
1769 Type RT2 = E2.ResultType (Row);
\r
1771 // If one of elements are string they both should be??? FIXME
\r
1772 if (t1 == typeof (string) || t2 == typeof (string)) {
\r
1774 //TempType = typeof (string);
\r
1775 if (t1 != typeof (string))
\r
1776 value1 = Convert.ChangeType (value1, Type.GetTypeCode (t2));
\r
1777 else if (t2 != typeof (string))
\r
1778 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1781 if (!Row.Table.CaseSensitive) {
\r
1782 value1 = ((string)value1).ToLower ();
\r
1783 value2 = ((string)value2).ToLower ();
\r
1786 else if (t1 != t2) {
\r
1788 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1791 else if (t1 != t2) {
\r
1793 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1796 object Result = t1.InvokeMember ("CompareTo", BindingFlags.Default |
\r
1797 BindingFlags.InvokeMethod, null,
\r
1799 new object [] {value2});
\r
1800 ReturnValue = (int)Result;
\r
1802 return ReturnValue;
\r
1806 /// Finds and creates Expression elements.
\r
1807 /// This presumes that expression is valid.
\r
1809 protected void ParseExpression (string s)
\r
1812 // TODO/FIXME: IMHO, this should be done with different kind of parsing:
\r
1813 // char by char not operand by operand.
\r
1816 string inside = ""; // stores string betwee parentheses like a = 12 and (b = 1 or b = 2)
\r
1817 string function = ""; // stores fuction paramters like substring (this, are, paramters)
\r
1822 // Find parenthesis
\r
1823 if ((temp = s.IndexOf ("(")) != -1) {
\r
1825 string functionName = "";
\r
1826 while (temp != 0 && s [temp - 1] != '=')
\r
1829 // Get the previous element of expression
\r
1830 while (s [temp] != '(') {
\r
1831 char c = s [temp];
\r
1832 functionName = functionName + c;
\r
1836 functionName = functionName.Trim ();
\r
1837 functionName = functionName.ToLower ();
\r
1839 // check if previous element is a function
\r
1840 if (!functionName.EndsWith ("convert") && !functionName.EndsWith ("len") &&
\r
1841 !functionName.EndsWith ("isnull") && !functionName.EndsWith ("iif") &&
\r
1842 !functionName.EndsWith ("trim") && !functionName.EndsWith ("substring") &&
\r
1843 !functionName.EndsWith ("sum") && !functionName.EndsWith ("avg") &&
\r
1844 !functionName.EndsWith ("min") && !functionName.EndsWith ("max") &&
\r
1845 !functionName.EndsWith ("count") && !functionName.EndsWith ("stdev") &&
\r
1846 !functionName.EndsWith ("var")) {
\r
1848 int startIndex = s.IndexOf ("(");
\r
1849 int i = startIndex + 1;
\r
1865 s = s.Remove (startIndex, i - startIndex);
\r
1870 string string1 = null;
\r
1871 string string2 = null;
\r
1872 if (FindOrElement (s, ref string1, ref string2))
\r
1873 CreateOrElement (string1, string2, inside);
\r
1875 else if (FindAndElement (s, ref string1, ref string2))
\r
1876 CreateAndElement (string1, string2, inside);
\r
1879 else if (FindLikeElement (s, ref string1, ref string2))
\r
1880 CreateLikeElement (string1, string2, inside);
\r
1883 else if (FindEqualElement (s, ref string1, ref string2))
\r
1884 CreateEqualsElement (string1, string2, inside);
\r
1887 else if (FindUnequalElement (s, ref string1, ref string2))
\r
1888 CreateUnequalsElement (string1, string2, inside);
\r
1891 else if (FindLessThanOrEqualElement (s, ref string1, ref string2))
\r
1892 CreateLessThanOrEqualElement (string1, string2, inside);
\r
1895 else if (FindLessThanElement (s, ref string1, ref string2))
\r
1896 CreateLessThanElement (string1, string2, inside);
\r
1899 else if (FindGreaterThanOrEqualElement (s, ref string1, ref string2))
\r
1900 CreateGreaterThanOrEqualElement (string1, string2, inside);
\r
1903 else if (FindGreaterThanElement (s, ref string1, ref string2))
\r
1904 CreateGreaterThanElement (string1, string2, inside);
\r
1906 // if there wasn't any operators like 'and' or 'not' there still could be
\r
1907 // arithmetic operators like '+' or '-' or functions like 'iif' or 'substring'
\r
1910 else if (FindMultiplyElement (s, ref string1, ref string2))
\r
1911 CreateMultiplyElement (string1, string2, inside);
\r
1914 else if (FindDivideElement (s, ref string1, ref string2))
\r
1915 CreateDivideElement (string1, string2, inside);
\r
1919 else if (FindAdditionElement (s, ref string1, ref string2))
\r
1920 CreateAdditionElement (string1, string2, inside);
\r
1923 else if (FindSubtractElement (s, ref string1, ref string2))
\r
1924 CreateSubtractionElement (string1, string2, inside);
\r
1927 else if (FindModulusElement (s, ref string1, ref string2))
\r
1928 CreateModulusElement (string1, string2, inside);
\r
1931 else if (FindAggregateElement (s, AGGREGATE.SUM))
\r
1932 Elements.Add (new ExpressionSum (s.Trim ()));
\r
1935 else if (FindAggregateElement (s, AGGREGATE.AVG))
\r
1936 Elements.Add (new ExpressionAvg (s.Trim ()));
\r
1939 else if (FindAggregateElement (s, AGGREGATE.MIN))
\r
1940 Elements.Add (new ExpressionMin (s.Trim ()));
\r
1943 else if (FindAggregateElement (s, AGGREGATE.MAX))
\r
1944 Elements.Add (new ExpressionMax (s.Trim ()));
\r
1947 else if (FindAggregateElement (s, AGGREGATE.COUNT))
\r
1948 Elements.Add (new ExpressionCount (s.Trim ()));
\r
1951 else if (FindAggregateElement (s, AGGREGATE.STDEV))
\r
1952 Elements.Add (new ExpressionStdev (s.Trim ()));
\r
1955 else if (FindAggregateElement (s, AGGREGATE.VAR))
\r
1956 Elements.Add (new ExpressionVar (s.Trim ()));
\r
1959 else if (FindLenElement (s))
\r
1960 Elements.Add (new ExpressionLen (s.Trim ()));
\r
1963 else if (FindIifElement (s))
\r
1964 Elements.Add (new ExpressionIif (s.Trim ()));
\r
1967 else if (FindIsNullElement (s))
\r
1968 Elements.Add (new ExpressionIsNull (s.Trim ()));
\r
1971 else if (FindSubstringElement (s))
\r
1972 Elements.Add (new ExpressionSubstring (s.Trim ()));
\r
1974 // if expression is like '(something someoperator something)'
\r
1975 else if (inside.Trim () != string.Empty)
\r
1976 ParseExpression (inside);
\r
1978 // At least, if it wasnt any of the above it is just normat string or int
\r
1981 Elements.Add (new ExpressionSingleElement (s.Trim ()));
\r
1984 #region CheckElement methods
\r
1987 // These methods are temporary for now
\r
1990 private bool FindOrElement (string s, ref string s1, ref string s2)
\r
1992 string stemp = s.ToLower ();
\r
1993 int indexOf = stemp.IndexOf("or");
\r
1995 if (indexOf == -1)
\r
1998 // Test if or is between ''
\r
1999 int oldIndex = -1;
\r
2000 while ((indexOf = stemp.IndexOf ("or", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2002 oldIndex = indexOf;
\r
2004 // check is the 'or' element part of string element
\r
2005 if (IsPartOfStringElement (stemp, indexOf))
\r
2008 // Check is or part of something else for example column name
\r
2009 if (indexOf != 0) {
\r
2011 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
2015 if (indexOf < s.Length + 2) {
\r
2017 if (stemp [indexOf + 2] != ' ' && stemp [indexOf + 2] != '\'')
\r
2021 if (IsPartOfFunction (stemp, indexOf))
\r
2024 s1 = s.Substring (0, indexOf).Trim ();
\r
2025 s2 = s.Substring (indexOf + 2).Trim ();
\r
2033 private bool FindAndElement (string s, ref string s1, ref string s2)
\r
2035 string stemp = s.ToLower ();
\r
2036 int indexOf = stemp.IndexOf("and");
\r
2038 if (indexOf == -1)
\r
2041 // Test if or is between ''
\r
2042 int oldIndex = -1;
\r
2043 while ((indexOf = stemp.IndexOf ("and", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2045 oldIndex = indexOf;
\r
2047 // check is the 'and' element part of string element
\r
2048 if (IsPartOfStringElement (stemp, indexOf))
\r
2052 // Check is or part of something else for example column name
\r
2053 if (indexOf != 0) {
\r
2055 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
2059 if (indexOf < stemp.Length + 3) {
\r
2061 if (stemp [indexOf + 3] != ' ' && stemp [indexOf + 3] != '\'')
\r
2065 if (IsPartOfFunction (stemp, indexOf))
\r
2069 s1 = s.Substring (0, indexOf).Trim ();
\r
2070 s2 = s.Substring (indexOf + 3).Trim ();
\r
2077 private bool FindLikeElement (string s, ref string s1, ref string s2)
\r
2079 string stemp = s.ToLower ();
\r
2080 int indexOf = stemp.IndexOf("like");
\r
2082 if (indexOf == -1)
\r
2085 // Test if or is between ''
\r
2086 int oldIndex = -1;
\r
2087 while ((indexOf = stemp.IndexOf ("like", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2089 oldIndex = indexOf;
\r
2091 // check is the 'and' element part of string element
\r
2092 if (IsPartOfStringElement (stemp, indexOf))
\r
2096 // Check is or part of something else for example column name
\r
2097 if (indexOf != 0) {
\r
2099 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
2103 if (indexOf < stemp.Length + 4) {
\r
2105 if (stemp [indexOf + 4] != ' ' && stemp [indexOf + 4] != '\'')
\r
2109 if (IsPartOfFunction (stemp, indexOf))
\r
2113 s1 = s.Substring (0, indexOf).Trim ();
\r
2114 s2 = s.Substring (indexOf + 4).Trim ();
\r
2121 private bool FindEqualElement (string s, ref string s1, ref string s2)
\r
2123 string stemp = s.ToLower ();
\r
2124 int indexOf = stemp.IndexOf ("=");
\r
2126 if (indexOf == -1)
\r
2129 int oldIndex = -1;
\r
2131 while ((indexOf = stemp.IndexOf ("=", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2133 oldIndex = indexOf;
\r
2135 // Check is the = part of <= or >=
\r
2136 if (stemp [indexOf - 1] == '<' || stemp [indexOf - 1] == '>')
\r
2139 // Check is the = element part of string element
\r
2140 if (IsPartOfStringElement (stemp, indexOf))
\r
2143 // Check is or part of column name
\r
2144 if (IsPartOfColumnName (stemp, indexOf))
\r
2147 if (IsPartOfFunction (stemp, indexOf))
\r
2150 s1 = s.Substring (0, indexOf).Trim ();
\r
2151 s2 = s.Substring (indexOf + 1).Trim ();
\r
2159 private bool FindUnequalElement (string s, ref string s1, ref string s2)
\r
2161 string stemp = s.ToLower ();
\r
2162 int indexOf = stemp.IndexOf ("<>");
\r
2164 if (stemp.IndexOf ("<>") == -1)
\r
2167 int oldIndex = -1;
\r
2168 while ((indexOf = stemp.IndexOf ("<>", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2170 oldIndex = indexOf;
\r
2172 // test if next charachter is something else than ' '
\r
2173 bool failed = false;
\r
2175 // Check is the <> element part of string element
\r
2176 if (IsPartOfStringElement (stemp, indexOf))
\r
2179 // Check is or part of column name
\r
2180 if (IsPartOfColumnName (stemp, indexOf))
\r
2183 if (IsPartOfFunction (stemp, indexOf))
\r
2186 s1 = s.Substring (0, indexOf).Trim ();
\r
2187 s2 = s.Substring (indexOf + 2).Trim ();
\r
2197 private bool FindLessThanElement (string s, ref string s1, ref string s2)
\r
2199 string stemp = s.ToLower ();
\r
2200 int indexOf = stemp.IndexOf ("<");
\r
2202 if (indexOf == -1)
\r
2205 int oldIndex = -1;
\r
2206 while ((indexOf = stemp.IndexOf ("<", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2208 oldIndex = indexOf;
\r
2210 // if < is part of <> or <=
\r
2211 if (stemp [indexOf + 1] == '>' || stemp [indexOf + 1] == '=')
\r
2214 // Test is < element part of string element
\r
2215 if (IsPartOfStringElement (stemp, indexOf))
\r
2218 // Check is or part of column name
\r
2219 if (IsPartOfColumnName (stemp, indexOf))
\r
2222 if (IsPartOfFunction (stemp, indexOf))
\r
2225 s1 = s.Substring (0, indexOf).Trim ();
\r
2226 s2 = s.Substring (indexOf + 1).Trim ();
\r
2234 private bool FindLessThanOrEqualElement (string s, ref string s1, ref string s2)
\r
2236 string stemp = s.ToLower ();
\r
2237 int indexOf = stemp.IndexOf ("<=");
\r
2239 if (indexOf == -1)
\r
2242 int oldIndex = -1;
\r
2243 while ((indexOf = stemp.IndexOf ("<=", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2245 oldIndex = indexOf;
\r
2246 // Test is <= element part of string element
\r
2247 if (IsPartOfStringElement (stemp, indexOf))
\r
2250 // Check is or part of column name
\r
2251 if (IsPartOfColumnName (stemp, indexOf))
\r
2254 if (IsPartOfFunction (stemp, indexOf))
\r
2257 s1 = s.Substring (0, indexOf).Trim ();
\r
2258 s2 = s.Substring (indexOf + 2).Trim ();
\r
2266 private bool FindGreaterThanElement (string s, ref string s1, ref string s2)
\r
2268 string stemp = s.ToLower ();
\r
2269 int indexOf = stemp.IndexOf (">");
\r
2271 if (indexOf == -1)
\r
2274 int oldIndex = -1;
\r
2275 while ((indexOf = stemp.IndexOf (">", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2277 oldIndex = indexOf;
\r
2279 // if < is part of <> or <=
\r
2280 if (stemp [indexOf - 1] == '<' || stemp [indexOf + 1] == '=')
\r
2283 // Test is < element part of string element
\r
2284 if (IsPartOfStringElement (stemp, indexOf))
\r
2287 // Check is or part of column name
\r
2288 if (IsPartOfColumnName (stemp, indexOf))
\r
2291 if (IsPartOfFunction (stemp, indexOf))
\r
2294 s1 = s.Substring (0, indexOf).Trim ();
\r
2295 s2 = s.Substring (indexOf + 1).Trim ();
\r
2302 private bool FindGreaterThanOrEqualElement (string s, ref string s1, ref string s2)
\r
2304 string stemp = s.ToLower ();
\r
2305 int indexOf = stemp.IndexOf (">=");
\r
2307 if (indexOf == -1)
\r
2310 int oldIndex = -1;
\r
2311 while ((indexOf = stemp.IndexOf (">=", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2313 oldIndex = indexOf;
\r
2314 bool failed = false;
\r
2315 // Test is <= element part of string element
\r
2317 // Check is or part of column name
\r
2318 if (IsPartOfColumnName (stemp, indexOf))
\r
2321 // is the element part of string element
\r
2322 if (IsPartOfStringElement (stemp, indexOf))
\r
2325 if (IsPartOfFunction (stemp, indexOf))
\r
2328 s1 = s.Substring (0, indexOf).Trim ();
\r
2329 s2 = s.Substring (indexOf + 2).Trim ();
\r
2337 private bool FindAdditionElement (string s, ref string s1, ref string s2)
\r
2339 string stemp = s.ToLower ();
\r
2340 int indexOf = stemp.IndexOf ("+");
\r
2342 if (indexOf == -1)
\r
2345 int oldIndex = -1;
\r
2346 while ((indexOf = stemp.IndexOf ("+", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2348 // FIXME: if '+' represents sign of integer
\r
2350 oldIndex = indexOf;
\r
2351 bool failed = false;
\r
2353 // Check is or part of column name
\r
2354 if (IsPartOfColumnName (stemp, indexOf))
\r
2357 // is the element part of string element
\r
2358 if (IsPartOfStringElement (stemp, indexOf))
\r
2361 if (IsPartOfFunction (stemp, indexOf))
\r
2364 s1 = s.Substring (0, indexOf).Trim ();
\r
2365 s2 = s.Substring (indexOf + 1).Trim ();
\r
2373 private bool FindSubtractElement (string s, ref string s1, ref string s2)
\r
2375 string stemp = s.ToLower ();
\r
2376 int indexOf = stemp.IndexOf ("-");
\r
2378 if (indexOf == -1)
\r
2381 int oldIndex = -1;
\r
2382 while ((indexOf = stemp.IndexOf ("-", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2384 oldIndex = indexOf;
\r
2385 bool failed = false;
\r
2387 // check is this lonely element
\r
2389 for (int i = indexOf - 1; i >= 0; i--) {
\r
2390 if (stemp [i] != ' ') {
\r
2399 // Check is or part of column name
\r
2400 if (IsPartOfColumnName (stemp, indexOf))
\r
2403 // is the element part of string element
\r
2404 if (IsPartOfStringElement (stemp, indexOf))
\r
2407 if (IsPartOfFunction (stemp, indexOf))
\r
2410 s1 = s.Substring (0, indexOf).Trim ();
\r
2411 s2 = s.Substring (indexOf + 1).Trim ();
\r
2419 private bool FindMultiplyElement (string s, ref string s1, ref string s2)
\r
2421 string stemp = s.ToLower ();
\r
2422 int indexOf = stemp.IndexOf ("*");
\r
2424 if (indexOf == -1)
\r
2427 int oldIndex = -1;
\r
2428 while ((indexOf = stemp.IndexOf ("*", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2431 oldIndex = indexOf;
\r
2432 bool failed = false;
\r
2434 // FIXME: If there is a divide operator before multiply operator.
\r
2436 // Check is or part of column name
\r
2437 if (IsPartOfColumnName (stemp, indexOf))
\r
2440 // is the element part of string element
\r
2441 if (IsPartOfStringElement (stemp, indexOf))
\r
2444 if (IsPartOfFunction (stemp, indexOf))
\r
2447 s1 = s.Substring (0, indexOf).Trim ();
\r
2448 s2 = s.Substring (indexOf + 1).Trim ();
\r
2456 private bool FindDivideElement (string s, ref string s1, ref string s2)
\r
2458 string stemp = s.ToLower ();
\r
2459 int indexOf = stemp.IndexOf ("/");
\r
2461 if (indexOf == -1)
\r
2464 int oldIndex = -1;
\r
2465 while ((indexOf = stemp.IndexOf ("/", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2468 oldIndex = indexOf;
\r
2469 bool failed = false;
\r
2471 // FIXME: If there is a multiply operator before divide operator.
\r
2473 // Check is or part of column name
\r
2474 if (IsPartOfColumnName (stemp, indexOf))
\r
2477 // is the element part of string element
\r
2478 if (IsPartOfStringElement (stemp, indexOf))
\r
2481 if (IsPartOfFunction (stemp, indexOf))
\r
2484 s1 = s.Substring (0, indexOf).Trim ();
\r
2485 s2 = s.Substring (indexOf + 1).Trim ();
\r
2493 private bool FindModulusElement (string s, ref string s1, ref string s2)
\r
2495 string stemp = s.ToLower ();
\r
2496 int indexOf = stemp.IndexOf ("%");
\r
2498 if (indexOf == -1)
\r
2501 int oldIndex = -1;
\r
2502 while ((indexOf = stemp.IndexOf ("%", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2505 oldIndex = indexOf;
\r
2506 bool failed = false;
\r
2508 // FIXME: If there is a multiply operator before divide operator.
\r
2510 // Check is or part of column name
\r
2511 if (IsPartOfColumnName (stemp, indexOf))
\r
2514 // is the element part of string element
\r
2515 if (IsPartOfStringElement (stemp, indexOf))
\r
2518 s1 = s.Substring (0, indexOf).Trim ();
\r
2519 s2 = s.Substring (indexOf + 1).Trim ();
\r
2527 private bool FindAggregateElement (string s, AGGREGATE aggregate)
\r
2529 string agg = null;
\r
2531 switch (aggregate) {
\r
2533 case AGGREGATE.SUM:
\r
2536 case AGGREGATE.AVG:
\r
2539 case AGGREGATE.MIN:
\r
2542 case AGGREGATE.MAX:
\r
2545 case AGGREGATE.COUNT:
\r
2548 case AGGREGATE.STDEV:
\r
2551 case AGGREGATE.VAR:
\r
2555 throw new NotImplementedException ();
\r
2559 string stemp = s.ToLower ();
\r
2560 int indexOf = stemp.IndexOf (agg);
\r
2562 if (indexOf == -1)
\r
2565 int oldIndex = -1;
\r
2566 while ((indexOf = stemp.IndexOf (agg, oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2568 oldIndex = indexOf;
\r
2569 bool failed = false;
\r
2571 // Check is or part of column name
\r
2572 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2575 // is the element part of string element
\r
2576 if (IsPartOfStringElement (stemp, indexOf))
\r
2587 private bool FindSumElement (string s)
\r
2589 string stemp = s.ToLower ();
\r
2590 int indexOf = stemp.IndexOf ("sum");
\r
2592 if (indexOf == -1)
\r
2595 int oldIndex = -1;
\r
2596 while ((indexOf = stemp.IndexOf ("sum", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2598 oldIndex = indexOf;
\r
2599 bool failed = false;
\r
2601 // Check is or part of column name
\r
2602 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2605 // is the element part of string element
\r
2606 if (IsPartOfStringElement (stemp, indexOf))
\r
2616 private bool FindAvgElement (string s)
\r
2618 string stemp = s.ToLower ();
\r
2619 int indexOf = stemp.IndexOf ("avg");
\r
2621 if (indexOf == -1)
\r
2624 int oldIndex = -1;
\r
2625 while ((indexOf = stemp.IndexOf ("avg", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2627 oldIndex = indexOf;
\r
2628 bool failed = false;
\r
2630 // Check is or part of column name
\r
2631 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2634 // is the element part of string element
\r
2635 if (IsPartOfStringElement (stemp, indexOf))
\r
2644 private bool FindMinElement (string s)
\r
2646 string stemp = s.ToLower ();
\r
2647 int indexOf = stemp.IndexOf ("min");
\r
2649 if (indexOf == -1)
\r
2652 int oldIndex = -1;
\r
2653 while ((indexOf = stemp.IndexOf ("min", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2655 oldIndex = indexOf;
\r
2656 bool failed = false;
\r
2658 // Check is or part of column name
\r
2659 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2662 // is the element part of string element
\r
2663 if (IsPartOfStringElement (stemp, indexOf))
\r
2672 private bool FindMaxElement (string s)
\r
2674 string stemp = s.ToLower ();
\r
2675 int indexOf = stemp.IndexOf ("max");
\r
2677 if (indexOf == -1)
\r
2680 int oldIndex = -1;
\r
2681 while ((indexOf = stemp.IndexOf ("max", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2683 oldIndex = indexOf;
\r
2684 bool failed = false;
\r
2686 // Check is or part of column name
\r
2687 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2690 // is the element part of string element
\r
2691 if (IsPartOfStringElement (stemp, indexOf))
\r
2700 private bool FindCountElement (string s)
\r
2702 string stemp = s.ToLower ();
\r
2703 int indexOf = stemp.IndexOf ("count");
\r
2705 if (indexOf == -1)
\r
2708 int oldIndex = -1;
\r
2709 while ((indexOf = stemp.IndexOf ("count", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2711 oldIndex = indexOf;
\r
2712 bool failed = false;
\r
2714 // Check is or part of column name
\r
2715 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2718 // is the element part of string element
\r
2719 if (IsPartOfStringElement (stemp, indexOf))
\r
2728 private bool FindStdevElement (string s)
\r
2730 string stemp = s.ToLower ();
\r
2731 int indexOf = stemp.IndexOf ("stdev");
\r
2733 if (indexOf == -1)
\r
2736 int oldIndex = -1;
\r
2737 while ((indexOf = stemp.IndexOf ("stdev", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2739 oldIndex = indexOf;
\r
2740 bool failed = false;
\r
2742 // Check is or part of column name
\r
2743 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2746 // is the element part of string element
\r
2747 if (IsPartOfStringElement (stemp, indexOf))
\r
2756 private bool FindVarElement (string s)
\r
2758 string stemp = s.ToLower ();
\r
2759 int indexOf = stemp.IndexOf ("var");
\r
2761 if (indexOf == -1)
\r
2764 int oldIndex = -1;
\r
2765 while ((indexOf = stemp.IndexOf ("var", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2767 oldIndex = indexOf;
\r
2768 bool failed = false;
\r
2770 // Check is or part of column name
\r
2771 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2774 // is the element part of string element
\r
2775 if (IsPartOfStringElement (stemp, indexOf))
\r
2784 private bool FindLenElement (string s)
\r
2786 string stemp = s.ToLower ();
\r
2787 int indexOf = stemp.IndexOf ("len");
\r
2789 if (indexOf == -1)
\r
2792 int oldIndex = -1;
\r
2793 while ((indexOf = stemp.IndexOf ("len", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2795 oldIndex = indexOf;
\r
2796 bool failed = false;
\r
2798 // Check is or part of column name
\r
2799 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2802 // is the element part of string element
\r
2803 if (IsPartOfStringElement (stemp, indexOf))
\r
2813 private bool FindIifElement (string s)
\r
2815 string stemp = s.ToLower ();
\r
2816 int indexOf = stemp.IndexOf ("iif");
\r
2818 if (indexOf == -1)
\r
2821 int oldIndex = -1;
\r
2822 while ((indexOf = stemp.IndexOf ("iif", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2824 oldIndex = indexOf;
\r
2825 bool failed = false;
\r
2827 // Check is or part of column name
\r
2828 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2831 // is the element part of string element
\r
2832 if (IsPartOfStringElement (stemp, indexOf))
\r
2841 private bool FindIsNullElement (string s)
\r
2843 string stemp = s.ToLower ();
\r
2844 int indexOf = stemp.IndexOf ("isnull");
\r
2846 if (indexOf == -1)
\r
2849 int oldIndex = -1;
\r
2850 while ((indexOf = stemp.IndexOf ("isnull", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2852 oldIndex = indexOf;
\r
2853 bool failed = false;
\r
2855 // Check is or part of column name
\r
2856 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2859 // is the element part of string element
\r
2860 if (IsPartOfStringElement (stemp, indexOf))
\r
2869 private bool FindSubstringElement (string s)
\r
2871 string stemp = s.ToLower ();
\r
2872 int indexOf = stemp.IndexOf ("substring");
\r
2874 if (indexOf == -1)
\r
2877 int oldIndex = -1;
\r
2878 while ((indexOf = stemp.IndexOf ("substring", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2880 oldIndex = indexOf;
\r
2881 bool failed = false;
\r
2883 // Check is or part of column name
\r
2884 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2887 // is the element part of string element
\r
2888 if (IsPartOfStringElement (stemp, indexOf))
\r
2898 #endregion // CheckElement methods
\r
2900 #region CreateElement methods
\r
2903 // These methods are going to be removed when way of parsing is changed
\r
2906 private void CreateOrElement (string s1, string s2, string inside)
\r
2908 CheckParenthesis (inside, ref s1, ref s2);
\r
2909 Elements.Add (new ExpressionOr (s1.Trim (), s2.Trim ()));
\r
2912 private void CreateAndElement (string s1, string s2, string inside)
\r
2914 CheckParenthesis (inside, ref s1, ref s2);
\r
2915 Elements.Add (new ExpressionAnd (s1.Trim (), s2.Trim ()));
\r
2918 private void CreateLikeElement (string s1, string s2, string inside)
\r
2920 CheckParenthesis (inside, ref s1, ref s2);
\r
2921 Elements.Add (new ExpressionLike (s1.Trim (), s2.Trim ()));
\r
2924 private void CreateEqualsElement (string s1, string s2, string inside)
\r
2926 CheckParenthesis (inside, ref s1, ref s2);
\r
2927 Elements.Add (new ExpressionEquals (s1.Trim (), s2.Trim ()));
\r
2930 private void CreateUnequalsElement (string s1, string s2, string inside)
\r
2932 CheckParenthesis (inside, ref s1, ref s2);
\r
2933 Elements.Add (new ExpressionUnequals (s1.Trim (), s2.Trim ()));
\r
2936 private void CreateLessThanElement (string s1, string s2, string inside)
\r
2938 CheckParenthesis (inside, ref s1, ref s2);
\r
2939 Elements.Add (new ExpressionLessThan (s1.Trim (), s2.Trim ()));
\r
2942 private void CreateLessThanOrEqualElement (string s1, string s2, string inside)
\r
2944 CheckParenthesis (inside, ref s1, ref s2);
\r
2945 Elements.Add (new ExpressionLessThanOrEqual (s1.Trim (), s2.Trim ()));
\r
2948 private void CreateGreaterThanElement (string s1, string s2, string inside)
\r
2950 CheckParenthesis (inside, ref s1, ref s2);
\r
2951 Elements.Add (new ExpressionGreaterThan (s1.Trim (), s2.Trim ()));
\r
2955 private void CreateGreaterThanOrEqualElement (string s1, string s2, string inside)
\r
2957 CheckParenthesis (inside, ref s1, ref s2);
\r
2958 Elements.Add (new ExpressionGreaterThanOrEqual (s1.Trim (), s2.Trim ()));
\r
2961 private void CreateAdditionElement (string s1, string s2, string inside)
\r
2963 CheckParenthesis (inside, ref s1, ref s2);
\r
2964 Elements.Add (new ExpressionAddition (s1.Trim (), s2.Trim ()));
\r
2967 private void CreateSubtractionElement (string s1, string s2, string inside)
\r
2969 CheckParenthesis (inside, ref s1, ref s2);
\r
2970 Elements.Add (new ExpressionSubtraction (s1.Trim (), s2.Trim ()));
\r
2973 private void CreateMultiplyElement (string s1, string s2, string inside)
\r
2975 CheckParenthesis (inside, ref s1, ref s2);
\r
2976 Elements.Add (new ExpressionMultiply (s1.Trim (), s2.Trim ()));
\r
2979 private void CreateDivideElement (string s1, string s2, string inside)
\r
2981 CheckParenthesis (inside, ref s1, ref s2);
\r
2982 Elements.Add (new ExpressionDivide (s1.Trim (), s2.Trim ()));
\r
2985 private void CreateModulusElement (string s1, string s2, string inside)
\r
2987 CheckParenthesis (inside, ref s1, ref s2);
\r
2988 Elements.Add (new ExpressionModulus (s1.Trim (), s2.Trim ()));
\r
2991 #endregion // CreateElemnt methods
\r
2993 #region Little helppers
\r
2995 private void CheckParenthesis (string inside, ref string s1, ref string s2)
\r
2997 if (s1 == string.Empty && inside != string.Empty)
\r
2999 else if (s2 == string.Empty && inside != string.Empty)
\r
3005 /// Checks is the element part of stringelement
\r
3007 private bool IsPartOfStringElement (string s, int indexOf)
\r
3009 // count how many '-charachters are before or. If count is odd it means or IS between quotes
\r
3011 for (int i = indexOf - 1; i >= 0; i--) {
\r
3012 if (s [i] == '\'')
\r
3016 if (quotes % 2 != 0)
\r
3023 /// Checks is the element part of column table
\r
3025 private bool IsPartOfColumnName (string s, int indexOf)
\r
3027 for (int i = indexOf; i >= 0; i--) {
\r
3029 // If the element is between [] it is part of columnname
\r
3030 if (s [i] == '\'' || s [i] == ']') {
\r
3033 else if (s [i] == '[') {
\r
3043 /// Checks are element part of function
\r
3045 private bool IsPartOfFunction (string s, int indexOf)
\r
3049 // If ',' or '\'' comes before '(' this element is not part of function's parameters
\r
3052 for (int i = indexOf; i >= 0; i--) {
\r
3054 if (s [i] == '(' || s [i] == ',') {
\r
3057 else if (s [i] == ')') {
\r
3065 #endregion // Little helppers
\r