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
74 for (int i = 0; i < s.Length; i++) {
\r
81 if ((c == '\n' || c == '\t') && quotes == 0)
\r
84 if (op == OP.OPERAND && c == '(')
\r
86 else if (op == OP.OPERAND && c == ')')
\r
89 if (c == ' ' && op == OP.OPERAND && (quotes % 2) == 0 && parentheses == 0) {
\r
92 newExp += strOperand;
\r
97 if (op == OP.OPERAND) {
\r
99 if (!Char.IsDigit (c) && isDigit && (quotes % 2) == 0) {
\r
101 newExp += strOperand;
\r
104 operatorType = OPERATOR_TYPE.UNDEFINED;
\r
110 if (op == OP.OPERATOR) {
\r
113 if (operatorType == OPERATOR_TYPE.UNDEFINED) {
\r
115 if (c == '<' || c == '=' || c == '>' || c == '*' || c == '/' || c == '%'
\r
116 || c == '-' || c == '+')
\r
118 operatorType = OPERATOR_TYPE.SYMBOLIC;
\r
120 operatorType = OPERATOR_TYPE.LITERAL;
\r
122 else if (operatorType == OPERATOR_TYPE.SYMBOLIC) {
\r
124 if (c != '<' && c != '=' && c != '>' && c != ' ') {
\r
126 // this is COPY-PASTE
\r
128 if (!newExp.EndsWith (" ") && !strOperator.StartsWith (" "))
\r
129 strOperator = " " + strOperator;
\r
131 newExp += strOperator;
\r
133 if (Char.IsDigit (c))
\r
136 strOperand = c.ToString ();
\r
143 if (operatorType == OPERATOR_TYPE.LITERAL && c == ' ') {
\r
145 newExp += strOperator;
\r
151 if (Char.IsDigit (c) && operatorType != OPERATOR_TYPE.LITERAL) {
\r
155 if (!newExp.EndsWith (" ") && !strOperator.StartsWith (" "))
\r
156 strOperator = " " + strOperator;
\r
157 newExp += strOperator;
\r
158 strOperand = c.ToString ();
\r
168 if (op == OP.OPERATOR)
\r
169 throw new SyntaxErrorException (
\r
170 "Missing operand after '" + strOperator + "' operator");
\r
172 newExp += strOperand;
\r
179 // O_P_E_R_A_T_O_R_S
\r
185 internal class ExpressionEquals : ExpressionElement
\r
188 public ExpressionEquals (string exp1, string exp2)
\r
192 ParseExpression (exp1);
\r
193 ParseExpression (exp2);
\r
196 public override bool Test (DataRow Row) {
\r
198 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
199 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
201 return ExpressionElement.Compare (E1, E2, Row) == 0;
\r
208 internal class ExpressionLessThan : ExpressionElement
\r
211 public ExpressionLessThan (string exp1, string exp2)
\r
215 ParseExpression (exp1);
\r
216 ParseExpression (exp2);
\r
219 public override bool Test (DataRow Row) {
\r
221 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
222 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
224 return ExpressionElement.Compare (E1, E2, Row) < 0;
\r
231 internal class ExpressionLessThanOrEqual : ExpressionElement
\r
234 public ExpressionLessThanOrEqual (string exp1, string exp2)
\r
238 ParseExpression (exp1);
\r
239 ParseExpression (exp2);
\r
242 public override bool Test (DataRow Row) {
\r
244 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
245 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
247 return ExpressionElement.Compare (E1, E2, Row) <= 0;
\r
254 internal class ExpressionGreaterThan : ExpressionElement
\r
257 public ExpressionGreaterThan (string exp1, string exp2)
\r
261 ParseExpression (exp1);
\r
262 ParseExpression (exp2);
\r
265 public override bool Test (DataRow Row) {
\r
267 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
268 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
270 return ExpressionElement.Compare (E1, E2, Row) > 0;
\r
277 internal class ExpressionGreaterThanOrEqual : ExpressionElement
\r
280 public ExpressionGreaterThanOrEqual (string exp1, string exp2)
\r
284 ParseExpression (exp1);
\r
285 ParseExpression (exp2);
\r
288 public override bool Test (DataRow Row) {
\r
290 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
291 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
293 return ExpressionElement.Compare (E1, E2, Row) >= 0;
\r
300 internal class ExpressionUnequals : ExpressionElement
\r
303 public ExpressionUnequals (string exp1, string exp2)
\r
307 ParseExpression (exp1);
\r
308 ParseExpression (exp2);
\r
311 public override bool Test (DataRow Row) {
\r
313 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
314 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
316 return ExpressionElement.Compare (E1, E2, Row) != 0;
\r
322 /// Class for LIKE-operator
\r
324 internal class ExpressionLike : ExpressionElement
\r
327 public ExpressionLike (string exp1, string exp2)
\r
329 ParseExpression (exp1);
\r
330 ParseExpression (exp2);
\r
333 public override bool Test (DataRow Row) {
\r
335 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
336 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
337 object value1 = E1.Result (Row);
\r
338 object value2 = E2.Result (Row);
\r
340 if (value1.GetType () != typeof (string) || value2.GetType () != typeof (string))
\r
341 throw new Exception (); // TODO: what exception
\r
343 string operand1 = value1.ToString ();
\r
344 string operand2 = value2.ToString ();
\r
346 // find out is there wildcards like * or %.
\r
347 while (operand2.EndsWith ("*") || operand2.EndsWith ("%"))
\r
348 operand2 = operand2.Remove (operand2.Length - 1, 1);
\r
349 while (operand2.StartsWith ("*") || operand2.StartsWith ("%"))
\r
350 operand2 = operand2.Remove (0, 1);
\r
355 indexOf = operand2.IndexOf ("*");
\r
356 while (indexOf != -1) {
\r
358 oldIndex = indexOf + 1;
\r
359 if (operand2 [indexOf + 1] != ']' || operand2 [indexOf - 1] != '[')
\r
360 throw new EvaluateException ("Error in Like operator: ther string pattern " + operand1 + " is invalid");
\r
362 operand2 = operand2.Remove (indexOf + 1, 1);
\r
363 operand2 = operand2.Remove (indexOf -1, 1);
\r
367 indexOf = operand2.IndexOf ("*", oldIndex);
\r
371 indexOf = operand2.IndexOf ("%");
\r
372 while (indexOf != -1) {
\r
374 oldIndex = indexOf + 1;
\r
376 if (operand2 [indexOf + 1] != ']' || operand2 [indexOf - 1] != '[')
\r
377 throw new EvaluateException ("Error in Like operator: ther string pattern " + operand2 + " is invalid");
\r
379 operand2 = operand2.Remove (indexOf + 1, 1);
\r
380 operand2 = operand2.Remove (indexOf -1, 1);
\r
384 indexOf = operand2.IndexOf ("%", oldIndex);
\r
387 int len2 = operand2.Length;
\r
388 int startIndex = 0;
\r
389 while ((startIndex + len2) <= operand1.Length) {
\r
390 if (String.Compare (operand1.Substring (startIndex, len2), operand2, !Row.Table.CaseSensitive) == 0)
\r
403 internal class ExpressionOr : ExpressionElement
\r
405 public ExpressionOr (string exp1, string exp2)
\r
407 ParseExpression (exp1);
\r
408 ParseExpression (exp2);
\r
411 public override bool Test (DataRow Row)
\r
413 foreach (ExpressionElement El in Elements) {
\r
425 internal class ExpressionAnd : ExpressionElement
\r
427 public ExpressionAnd (string exp1, string exp2)
\r
429 ParseExpression (exp1);
\r
430 ParseExpression (exp2);
\r
433 public override object Result (DataRow Row) {
\r
438 public override bool Test (DataRow Row)
\r
440 foreach (ExpressionElement El in Elements) {
\r
441 if (!El.Test (Row))
\r
451 // A_R_I_T_H_M_E_T_I_C O_P_E_R_A_T_O_R_S
\r
457 internal class ExpressionAddition : ExpressionElement
\r
459 public ExpressionAddition (string exp1, string exp2)
\r
463 ParseExpression (exp1);
\r
464 ParseExpression (exp2);
\r
467 public override Type ResultType (DataRow Row)
\r
469 Type ResultType = typeof (string);
\r
470 ExpressionElement exp1Temp = ((ExpressionElement)Elements [0]);
\r
471 ExpressionElement exp2Temp = ((ExpressionElement)Elements [1]);
\r
473 if (exp1Temp.ResultType (Row) == typeof (string) || exp2Temp.ResultType (Row) == typeof (string))
\r
474 ResultType = typeof (string);
\r
476 else if (exp1Temp.ResultType (Row) == typeof (long) || exp2Temp.ResultType (Row) == typeof (long))
\r
477 ResultType = typeof (long);
\r
479 else if (exp1Temp.ResultType (Row) == typeof (int) || exp2Temp.ResultType (Row) == typeof (int))
\r
480 ResultType = typeof (int);
\r
485 public override object Result (DataRow Row)
\r
487 return CalculateResult (Row);
\r
490 protected override object Calculate (object value1, object value2, Type TempType)
\r
492 object Result = null;
\r
494 if (TempType == typeof (string))
\r
495 Result = (string)value1 + (string)value2;
\r
496 else if (TempType == typeof (long))
\r
497 Result = (long)value1 + (long)value2;
\r
498 else if (TempType == typeof (int))
\r
499 Result = (int)value1 + (int)value2;
\r
500 else if (TempType == typeof (short))
\r
501 Result = (short)value1 + (short)value2;
\r
502 else if (TempType == typeof (ulong))
\r
503 Result = (ulong)value1 + (ulong)value2;
\r
504 else if (TempType == typeof (uint))
\r
505 Result = (uint)value1 + (uint)value2;
\r
506 else if (TempType == typeof (ushort))
\r
507 Result = (ushort)value1 + (ushort)value2;
\r
508 else if (TempType == typeof (byte))
\r
509 Result = (byte)value1 + (byte)value2;
\r
510 else if (TempType == typeof (sbyte))
\r
511 Result = (sbyte)value1 + (sbyte)value2;
\r
513 //else if (TempType == typeof (bool))
\r
514 // Result = (bool)value1 + (bool)value2;
\r
515 else if (TempType == typeof (float))
\r
516 Result = (float)value1 + (float)value2;
\r
517 else if (TempType == typeof (double))
\r
518 Result = (double)value1 + (double)value2;
\r
519 else if (TempType == typeof (decimal))
\r
520 Result = (decimal)value1 + (decimal)value2;
\r
522 //else if (TempType == typeof (DateTime))
\r
523 // Result = (DateTime)value1 + (DateTime)value2;
\r
529 // This method is shouldnt never invoked
\r
530 public override bool Test (DataRow Row)
\r
532 throw new EvaluateException ();
\r
539 internal class ExpressionSubtraction : ExpressionElement
\r
541 public ExpressionSubtraction (string exp1, string exp2)
\r
545 ParseExpression (exp1);
\r
546 ParseExpression (exp2);
\r
549 public override object Result (DataRow Row)
\r
551 return CalculateResult (Row);
\r
554 // This method is shouldnt never invoked
\r
555 public override bool Test (DataRow Row)
\r
557 throw new EvaluateException ();
\r
560 protected override object Calculate (object value1, object value2, Type TempType)
\r
562 object Result = null;
\r
565 //if (TempType == typeof (string))
\r
566 // Result = (string)value1 - (string)value2;
\r
567 if (TempType == typeof (long))
\r
568 Result = (long)value1 - (long)value2;
\r
569 else if (TempType == typeof (int))
\r
570 Result = (int)value1 - (int)value2;
\r
571 else if (TempType == typeof (short))
\r
572 Result = (short)value1 - (short)value2;
\r
573 else if (TempType == typeof (ulong))
\r
574 Result = (ulong)value1 + (ulong)value2;
\r
575 else if (TempType == typeof (uint))
\r
576 Result = (uint)value1 - (uint)value2;
\r
577 else if (TempType == typeof (ushort))
\r
578 Result = (ushort)value1 - (ushort)value2;
\r
579 else if (TempType == typeof (byte))
\r
580 Result = (byte)value1 - (byte)value2;
\r
581 else if (TempType == typeof (sbyte))
\r
582 Result = (sbyte)value1 - (sbyte)value2;
\r
584 //else if (TempType == typeof (bool))
\r
585 // Result = (bool)value1 - (bool)value2;
\r
586 else if (TempType == typeof (float))
\r
587 Result = (float)value1 - (float)value2;
\r
588 else if (TempType == typeof (double))
\r
589 Result = (double)value1 - (double)value2;
\r
590 else if (TempType == typeof (decimal))
\r
591 Result = (decimal)value1 - (decimal)value2;
\r
593 //else if (TempType == typeof (DateTime))
\r
594 // Result = (DateTime)value1 - (DateTime)value2;
\r
603 internal class ExpressionMultiply : ExpressionElement
\r
605 public ExpressionMultiply (string exp1, string exp2)
\r
609 ParseExpression (exp1);
\r
610 ParseExpression (exp2);
\r
613 public override Type ResultType (DataRow Row)
\r
615 Type ResultType = null;
\r
616 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
617 ExpressionElement E2 = ((ExpressionElement)Elements [1]);
\r
618 Type t1 = E1.ResultType (Row);
\r
619 Type t2 = E2.ResultType (Row);
\r
621 if (t1 == typeof (string) || t2 == typeof (string))
\r
622 throw new EvaluateException ("Cannon perform '*' operation on " + t1.ToString () +
\r
623 " and " + t2.ToString ());
\r
625 else if (t1 == typeof (long) || t2 == typeof (long))
\r
626 ResultType = typeof (long);
\r
628 else if (t1 == typeof (int) || t2 == typeof (int))
\r
629 ResultType = typeof (int);
\r
634 public override object Result (DataRow Row)
\r
636 return CalculateResult (Row);
\r
639 public override bool Test (DataRow Row)
\r
641 throw new EvaluateException ();
\r
644 protected override object Calculate (object value1, object value2, Type TempType)
\r
646 object Result = null;
\r
648 if (TempType == typeof (long))
\r
649 Result = (long)value1 * (long)value2;
\r
650 else if (TempType == typeof (int))
\r
651 Result = (int)value1 * (int)value2;
\r
652 else if (TempType == typeof (short))
\r
653 Result = (short)value1 * (short)value2;
\r
654 else if (TempType == typeof (ulong))
\r
655 Result = (ulong)value1 * (ulong)value2;
\r
656 else if (TempType == typeof (uint))
\r
657 Result = (uint)value1 * (uint)value2;
\r
658 else if (TempType == typeof (ushort))
\r
659 Result = (ushort)value1 * (ushort)value2;
\r
660 else if (TempType == typeof (byte))
\r
661 Result = (byte)value1 * (byte)value2;
\r
662 else if (TempType == typeof (sbyte))
\r
663 Result = (sbyte)value1 * (sbyte)value2;
\r
665 //else if (TempType == typeof (bool))
\r
666 // Result = (bool)value1 * (bool)value2;
\r
667 else if (TempType == typeof (float))
\r
668 Result = (float)value1 * (float)value2;
\r
669 else if (TempType == typeof (double))
\r
670 Result = (double)value1 * (double)value2;
\r
671 else if (TempType == typeof (decimal))
\r
672 Result = (decimal)value1 * (decimal)value2;
\r
674 //else if (TempType == typeof (DateTime))
\r
675 // Result = (DateTime)value1 * (DateTime)value2;
\r
685 internal class ExpressionDivide : ExpressionElement
\r
687 public ExpressionDivide (string exp1, string exp2)
\r
691 ParseExpression (exp1);
\r
692 ParseExpression (exp2);
\r
695 public override object Result (DataRow Row)
\r
697 return CalculateResult (Row);
\r
700 // This method is shouldnt never invoked
\r
701 public override bool Test (DataRow Row)
\r
703 throw new EvaluateException ();
\r
706 protected override object Calculate (object value1, object value2, Type TempType)
\r
708 object Result = null;
\r
710 if (TempType == typeof (long))
\r
711 Result = (long)value1 / (long)value2;
\r
713 //else if (TempType == typeof (int))
\r
714 // Result = (string)value1 / (string)value2;
\r
715 else if (TempType == typeof (int))
\r
716 Result = (int)value1 / (int)value2;
\r
717 else if (TempType == typeof (short))
\r
718 Result = (short)value1 / (short)value2;
\r
719 else if (TempType == typeof (ulong))
\r
720 Result = (ulong)value1 / (ulong)value2;
\r
721 else if (TempType == typeof (uint))
\r
722 Result = (uint)value1 / (uint)value2;
\r
723 else if (TempType == typeof (ushort))
\r
724 Result = (ushort)value1 / (ushort)value2;
\r
725 else if (TempType == typeof (byte))
\r
726 Result = (byte)value1 / (byte)value2;
\r
727 else if (TempType == typeof (sbyte))
\r
728 Result = (sbyte)value1 / (sbyte)value2;
\r
730 //else if (TempType == typeof (bool))
\r
731 // Result = (bool)value1 // (bool)value2;
\r
732 else if (TempType == typeof (float))
\r
733 Result = (float)value1 / (float)value2;
\r
734 else if (TempType == typeof (double))
\r
735 Result = (double)value1 / (double)value2;
\r
736 else if (TempType == typeof (decimal))
\r
737 Result = (decimal)value1 / (decimal)value2;
\r
739 //else if (TempType == typeof (DateTime))
\r
740 // Result = (DateTime)value1 / (DateTime)value2;
\r
749 internal class ExpressionModulus : ExpressionElement
\r
751 public ExpressionModulus (string exp1, string exp2)
\r
755 ParseExpression (exp1);
\r
756 ParseExpression (exp2);
\r
759 public override object Result (DataRow Row)
\r
761 return CalculateResult (Row);
\r
764 // This method is shouldnt never invoked
\r
765 public override bool Test (DataRow Row)
\r
767 throw new EvaluateException ();
\r
770 protected override object Calculate (object value1, object value2, Type TempType)
\r
772 object Result = null;
\r
774 if (TempType == typeof (long))
\r
775 Result = (long)value1 % (long)value2;
\r
777 //else if (TempType == typeof (int))
\r
778 // Result = (string)value1 % (string)value2;
\r
779 else if (TempType == typeof (int))
\r
780 Result = (int)value1 % (int)value2;
\r
781 else if (TempType == typeof (short))
\r
782 Result = (short)value1 % (short)value2;
\r
783 else if (TempType == typeof (ulong))
\r
784 Result = (ulong)value1 % (ulong)value2;
\r
785 else if (TempType == typeof (uint))
\r
786 Result = (uint)value1 % (uint)value2;
\r
787 else if (TempType == typeof (ushort))
\r
788 Result = (ushort)value1 % (ushort)value2;
\r
789 else if (TempType == typeof (byte))
\r
790 Result = (byte)value1 % (byte)value2;
\r
791 else if (TempType == typeof (sbyte))
\r
792 Result = (sbyte)value1 % (sbyte)value2;
\r
794 //else if (TempType == typeof (bool))
\r
795 // Result = (bool)value1 // (bool)value2;
\r
796 else if (TempType == typeof (float))
\r
797 Result = (float)value1 % (float)value2;
\r
798 else if (TempType == typeof (double))
\r
799 Result = (double)value1 % (double)value2;
\r
800 else if (TempType == typeof (decimal))
\r
801 Result = (decimal)value1 % (decimal)value2;
\r
803 //else if (TempType == typeof (DateTime))
\r
804 // Result = (DateTime)value1 / (DateTime)value2;
\r
811 // _____A_G_G_R_E_G_A_T_E_S_____
\r
814 internal class ExpressionAggregate : ExpressionElement
\r
816 //public override object Result (DataRow Row)
\r
821 public override bool Test (DataRow Row)
\r
823 throw new EvaluateException ();
\r
826 protected virtual void ParseParameters (string s)
\r
828 string stemp = s.ToLower ();
\r
829 bool inString = false;
\r
833 while (!s.StartsWith ("("))
\r
834 s = s.Remove (0, 1);
\r
837 s = s.Remove (0, 1);
\r
839 int parentheses = 0;
\r
840 for (int i = 0; i < s.Length; i++) {
\r
843 inString = !inString;
\r
844 else if (s [i] == '(')
\r
846 else if (s [i] == ')')
\r
849 if ((s [i] == ',' || s [i] == ')') && !inString && parentheses == -1) { // Parameter changed
\r
852 p1 = s.Substring (0, i);
\r
859 throw new Exception ();
\r
861 ParseExpression (p1);
\r
867 /// Class for Sum (column_Name)
\r
869 internal class ExpressionSum : ExpressionAggregate
\r
871 public ExpressionSum (string exp1)
\r
873 ParseParameters (exp1);
\r
876 public override object Result (DataRow Row)
\r
878 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
879 object value1 = E1.Result (Row);
\r
880 Type t1 = value1.GetType ();
\r
881 object result = null;
\r
883 // This could be optimized. If E1 is single element (Not child or parent) the
\r
884 // result of Sum() aggregate is allways same
\r
886 if (E1 is ExpressionSingleElement) {
\r
888 // This should be optimized somehow
\r
889 foreach (DataRow tempRow in Row.Table.Rows) {
\r
891 // TODO: other types and exceptions
\r
892 object v = E1.Result (tempRow);
\r
895 if (v == null || v == DBNull.Value)
\r
898 if (t1 == typeof (long)) {
\r
900 result = (long)result + (long)v;
\r
902 else if (t1 == typeof (int)) {
\r
904 result = (int)result + (int)v;
\r
906 else if (t1 == typeof (short)) {
\r
908 result = (short)result + (short)v;
\r
910 else if (t1 == typeof (double)) {
\r
912 result = (double)result + (double)v;
\r
914 else if (t1 == typeof (float)) {
\r
916 result = (float)result + (float)v;
\r
919 throw new NotImplementedException ();
\r
927 // FIXME: This method is copy-paste in every Aggregate class.
\r
932 /// Class for Avg (column_Name)
\r
934 internal class ExpressionAvg : ExpressionAggregate
\r
936 public ExpressionAvg (string exp1)
\r
938 ParseParameters (exp1);
\r
942 /// This is used from ExpressionStdDev for evaluating avg.
\r
944 public ExpressionAvg (ExpressionElement E)
\r
949 public override object Result (DataRow Row)
\r
951 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
952 object value1 = E1.Result (Row);
\r
953 Type original = value1.GetType ();
\r
954 object result = null;
\r
956 if (E1 is ExpressionSingleElement) {
\r
959 // This should be optimized somehow
\r
960 foreach (DataRow tempRow in Row.Table.Rows) {
\r
962 // TODO: other types and exceptions
\r
963 object v = E1.Result (tempRow);
\r
965 if (v == null || v == DBNull.Value)
\r
970 if (result == null)
\r
973 if (t1 == typeof (long)) {
\r
974 result = (long)result + (long)v;
\r
976 else if (t1 == typeof (int)) {
\r
977 result = (int)result + (int)v;
\r
979 else if (t1 == typeof (short)) {
\r
980 result = (short)result + (short)v;
\r
982 else if (t1 == typeof (double)) {
\r
983 result = (double)result + (double)v;
\r
985 else if (t1 == typeof (float)) {
\r
986 result = (float)result + (float)v;
\r
989 throw new NotImplementedException ();
\r
994 if (t1 == typeof (long))
\r
995 result = (long)result / Row.Table.Rows.Count;
\r
996 else if (t1 == typeof (int))
\r
997 result = (int)result / Row.Table.Rows.Count;
\r
998 else if (t1 == typeof (short))
\r
999 result = (short)result / Row.Table.Rows.Count;
\r
1000 else if (t1 == typeof (double))
\r
1001 result = (double)result / Row.Table.Rows.Count;
\r
1009 /// Class for Min (column_Name)
\r
1011 internal class ExpressionMin : ExpressionAggregate
\r
1013 public ExpressionMin (string exp1)
\r
1015 ParseParameters (exp1);
\r
1018 public override object Result (DataRow Row)
\r
1020 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1021 object value1 = E1.Result (Row);
\r
1022 Type original = value1.GetType ();
\r
1023 object result = null;
\r
1025 if (E1 is ExpressionSingleElement) {
\r
1028 // This should be optimized somehow
\r
1029 foreach (DataRow tempRow in Row.Table.Rows) {
\r
1031 // TODO: other types and exceptions
\r
1032 object v = E1.Result (tempRow);
\r
1034 if (v == null || v == DBNull.Value)
\r
1037 t1 = v.GetType ();
\r
1039 if (result == null)
\r
1042 object CompResult = t1.InvokeMember ("CompareTo", BindingFlags.Default |
\r
1043 BindingFlags.InvokeMethod, null,
\r
1045 new object [] {result});
\r
1047 if ((int)CompResult < 0)
\r
1058 /// Class for Max (column_Name)
\r
1060 internal class ExpressionMax : ExpressionAggregate
\r
1062 public ExpressionMax (string exp1)
\r
1064 ParseParameters (exp1);
\r
1067 public override object Result (DataRow Row)
\r
1069 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1070 object value1 = E1.Result (Row);
\r
1071 Type original = value1.GetType ();
\r
1072 object result = null;
\r
1074 if (E1 is ExpressionSingleElement) {
\r
1077 // This should be optimized somehow
\r
1078 foreach (DataRow tempRow in Row.Table.Rows) {
\r
1080 // TODO: other types and exceptions
\r
1081 object v = E1.Result (tempRow);
\r
1083 if (v == null || v == DBNull.Value)
\r
1086 t1 = v.GetType ();
\r
1088 if (result == null)
\r
1091 object CompResult = t1.InvokeMember ("CompareTo", BindingFlags.Default |
\r
1092 BindingFlags.InvokeMethod, null,
\r
1094 new object [] {result});
\r
1096 if ((int)CompResult > 0)
\r
1108 /// Class for count (column)
\r
1110 internal class ExpressionCount : ExpressionAggregate
\r
1112 public ExpressionCount (string exp1)
\r
1114 ParseParameters (exp1);
\r
1117 public override object Result (DataRow Row)
\r
1119 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1122 if (E1 is ExpressionSingleElement) {
\r
1124 // This should be optimized somehow
\r
1125 foreach (DataRow tempRow in Row.Table.Rows) {
\r
1137 /// Class for StdDev (column)
\r
1139 internal class ExpressionStdev : ExpressionAggregate
\r
1141 public ExpressionStdev (string exp1)
\r
1143 ParseParameters (exp1);
\r
1146 public override object Result (DataRow Row)
\r
1148 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1149 ExpressionAvg Avg = new ExpressionAvg (E1);
\r
1151 object tempAvg = Avg.Result (Row);
\r
1154 double result = 0;
\r
1156 if (tempAvg.GetType () == typeof (int))
\r
1157 avg = (double)(int)tempAvg;
\r
1159 if (E1 is ExpressionSingleElement) {
\r
1161 foreach (DataRow tempRow in Row.Table.Rows) {
\r
1165 object v = E1.Result (tempRow);
\r
1167 if (v == null || v == DBNull.Value)
\r
1170 if (v.GetType () == typeof (long))
\r
1171 sum = avg - (long)v;
\r
1172 else if (v.GetType () == typeof (int))
\r
1173 sum = avg - (int)v;
\r
1174 else if (v.GetType () == typeof (short))
\r
1175 sum = avg - (short)v;
\r
1177 throw new NotImplementedException ();
\r
1179 result += Math.Pow (sum, 2);
\r
1182 result = result / (Row.Table.Rows.Count - 1);
\r
1183 result = Math.Sqrt (result);
\r
1191 /// Class for Var (column)
\r
1193 internal class ExpressionVar : ExpressionAggregate
\r
1195 public ExpressionVar (string exp1)
\r
1197 ParseParameters (exp1);
\r
1200 public override object Result (DataRow Row)
\r
1202 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1203 ExpressionAvg Avg = new ExpressionAvg (E1);
\r
1205 object tempAvg = Avg.Result (Row);
\r
1208 double result = 0;
\r
1210 if (tempAvg.GetType () == typeof (int))
\r
1211 avg = (double)(int)tempAvg;
\r
1213 if (E1 is ExpressionSingleElement) {
\r
1215 foreach (DataRow tempRow in Row.Table.Rows) {
\r
1219 object v = E1.Result (tempRow);
\r
1221 if (v == null || v == DBNull.Value)
\r
1224 if (v.GetType () == typeof (long))
\r
1225 sum = avg - (long)v;
\r
1226 else if (v.GetType () == typeof (int))
\r
1227 sum = avg - (int)v;
\r
1228 else if (v.GetType () == typeof (short))
\r
1229 sum = avg - (short)v;
\r
1231 throw new NotImplementedException ();
\r
1233 result += Math.Pow (sum, 2);
\r
1236 result = result / (Row.Table.Rows.Count - 1);
\r
1244 // _____F_U_ N_C_T_I_O_N_S_______
\r
1248 /// Class for len (string) function
\r
1250 internal class ExpressionLen : ExpressionElement
\r
1252 public ExpressionLen (string exp1)
\r
1254 _ResultType = typeof (int);
\r
1255 ParseParameters (exp1);
\r
1258 public override object Result (DataRow Row)
\r
1260 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1261 object value1 = E1.Result (Row);
\r
1263 return value1.ToString ().Length;
\r
1266 public override bool Test (DataRow Row)
\r
1268 throw new EvaluateException ();
\r
1271 public void ParseParameters (string s)
\r
1273 string stemp = s.ToLower ();
\r
1274 bool inString = false;
\r
1278 while (!s.StartsWith ("("))
\r
1279 s = s.Remove (0, 1);
\r
1282 s = s.Remove (0, 1);
\r
1283 int parentheses = 0;
\r
1284 for (int i = 0; i < s.Length; i++) {
\r
1286 if (s [i] == '\'')
\r
1287 inString = !inString;
\r
1288 else if (s [i] == '(')
\r
1290 else if (s [i] == ')')
\r
1293 if ((s [i] == ',' || s [i] == ')') && !inString && parentheses == -1) { // Parameter changed
\r
1296 p1 = s.Substring (0, i);
\r
1303 throw new Exception ();
\r
1305 ParseExpression (p1);
\r
1310 /// Class for iif (exp1, truepart, falsepart) function
\r
1312 internal class ExpressionIif : ExpressionElement
\r
1314 public ExpressionIif (string exp)
\r
1316 ParseParameters (exp);
\r
1319 public override object Result (DataRow Row)
\r
1321 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1322 ExpressionElement E2 = ((ExpressionElement)Elements [1]);
\r
1323 ExpressionElement E3 = ((ExpressionElement)Elements [2]);
\r
1325 if (E1.Test (Row)) // expression
\r
1326 return E2.Result (Row); // truepart
\r
1328 return E3.Result (Row); // false part
\r
1331 // This method is shouldnt never invoked
\r
1332 public override bool Test (DataRow Row)
\r
1334 throw new EvaluateException ();
\r
1337 public override Type ResultType (DataRow Row)
\r
1339 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1340 ExpressionElement E2 = ((ExpressionElement)Elements [1]);
\r
1341 ExpressionElement E3 = ((ExpressionElement)Elements [2]);
\r
1343 if (E1.Test (Row)) // expression
\r
1344 return E2.Result (Row).GetType (); // truepart
\r
1346 return E3.Result (Row).GetType (); // false part
\r
1350 /// Parses expressions in parameters (exp, truepart, falsepart)
\r
1352 private void ParseParameters (string s)
\r
1354 bool inString = false;
\r
1355 string stemp = s.ToLower ();
\r
1359 s = s.Substring (stemp.IndexOf ("iif") + 3);
\r
1362 while (!s.StartsWith ("("))
\r
1363 s = s.Remove (0, 1);
\r
1366 s = s.Remove (0, 1);
\r
1367 int parentheses = 0;
\r
1368 for (int i = 0; i < s.Length; i++) {
\r
1370 if (s [i] == '\'')
\r
1371 inString = !inString;
\r
1372 else if (s [i] == '(')
\r
1374 else if (s [i] == ')')
\r
1377 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1378 (s [i] == ')' && i == (s.Length -1))) { // Parameter changed
\r
1381 p1 = s.Substring (0, i);
\r
1382 s = s.Substring (i + 1);
\r
1386 else if (p2 == null) {
\r
1387 p2 = s.Substring (0, i);
\r
1388 s = s.Substring (i + 1);
\r
1392 else if (p3 == null) {
\r
1393 p3 = s.Substring (0, i);
\r
1394 s = s.Substring (i + 1);
\r
1399 throw new Exception (); // FIXME: What exception
\r
1403 if (p1 == null || p2 == null || p3 == null)
\r
1404 throw new Exception ();
\r
1406 ParseExpression (p1);
\r
1407 ParseExpression (p2);
\r
1408 ParseExpression (p3);
\r
1413 /// Class for isnull (expression, returnvalue) function
\r
1415 internal class ExpressionIsNull : ExpressionElement
\r
1417 public ExpressionIsNull (string exp)
\r
1419 ParseParameters (exp);
\r
1422 public override object Result (DataRow Row)
\r
1424 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1425 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
1427 object R1 = E1.Result (Row);
\r
1428 object value1 = null;
\r
1429 if (R1 == null || R1 == DBNull.Value)
\r
1430 return E2.Result (Row);
\r
1435 public override Type ResultType (DataRow Row)
\r
1437 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1438 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
1440 object R1 = E1.Result (Row);
\r
1441 object value1 = null;
\r
1442 if (R1 == null || R1 == DBNull.Value)
\r
1443 return E2.Result (Row).GetType ();
\r
1445 return R1.GetType ();
\r
1449 /// IsNull function does not return boolean value, so throw exception
\r
1451 public override bool Test (DataRow Row)
\r
1453 throw new EvaluateException ();
\r
1457 /// Parses parameters of function and invoke ParseExpression methods
\r
1459 private void ParseParameters (string s)
\r
1461 bool inString = false;
\r
1462 string stemp = s.ToLower ();
\r
1466 s = s.Substring (stemp.IndexOf ("isnull") + 6);
\r
1469 while (!s.StartsWith ("("))
\r
1470 s = s.Remove (0, 1);
\r
1473 s = s.Remove (0, 1);
\r
1474 int parentheses = 0;
\r
1475 for (int i = 0; i < s.Length; i++) {
\r
1477 if (s [i] == '\'')
\r
1478 inString = !inString;
\r
1479 else if (s [i] == '(')
\r
1481 else if (s [i] == ')')
\r
1484 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1485 (s [i] == ')' && i == (s.Length -1))) { // Parameter changed
\r
1488 p1 = s.Substring (0, i);
\r
1489 s = s.Substring (i + 1);
\r
1493 else if (p2 == null) {
\r
1494 p2 = s.Substring (0, i);
\r
1495 s = s.Substring (i + 1);
\r
1500 throw new Exception (); // FIXME: What exception
\r
1504 if (p1 == null || p2 == null)
\r
1505 throw new Exception ();
\r
1507 ParseExpression (p1);
\r
1508 ParseExpression (p2);
\r
1513 /// Class for Substring (expression, start, length) function
\r
1515 internal class ExpressionSubstring : ExpressionElement
\r
1517 public ExpressionSubstring (string exp)
\r
1519 ParseParameters (exp);
\r
1520 _ResultType = typeof (string);
\r
1523 public override object Result (DataRow Row)
\r
1525 ExpressionElement E1 = (ExpressionElement)Elements [0];
\r
1526 ExpressionElement E2 = (ExpressionElement)Elements [1];
\r
1527 ExpressionElement E3 = (ExpressionElement)Elements [2];
\r
1529 object value1 = E1.Result (Row);
\r
1530 object value2 = E2.Result (Row);
\r
1531 object value3 = E3.Result (Row);
\r
1532 Type t1 = value1.GetType ();
\r
1533 Type t2 = value2.GetType ();
\r
1534 Type t3 = value3.GetType ();
\r
1536 if (value1 == null || value2 == null || value3 == null
\r
1537 || value1 == DBNull.Value || value2 == DBNull.Value || value3 == DBNull.Value)
\r
1538 return string.Empty;
\r
1540 if (t1 != typeof (string))
\r
1541 throw new Exception (); // FIXME: what exception
\r
1542 else if (t2 != typeof (int))
\r
1543 throw new EvaluateException ("Type mismatch is function argument: Substring (), argument 2, excepted System.Int32");
\r
1544 else if (t3 != typeof (int))
\r
1545 throw new EvaluateException ("Type mismatch is function argument: Substring (), argument 3, excepted System.Int32");
\r
1547 string str = value1.ToString ();
\r
1548 int start = (int)value2;
\r
1549 int length = (int)value3;
\r
1551 if (str.Length < start)
\r
1552 str = string.Empty;
\r
1554 if ((start + length - 1) > str.Length)
\r
1555 str = str.Substring (start - 1);
\r
1557 str = str.Substring (start - 1, length);
\r
1564 /// IsNull function does not return boolean value, so throw exception
\r
1566 public override bool Test (DataRow Row)
\r
1568 throw new EvaluateException ();
\r
1572 /// Parses parameters of function and invoke ParseExpression methods
\r
1574 private void ParseParameters (string s)
\r
1576 bool inString = false;
\r
1577 string stemp = s.ToLower ();
\r
1582 s = s.Substring (stemp.IndexOf ("substring") + 9);
\r
1585 while (!s.StartsWith ("("))
\r
1586 s = s.Remove (0, 1);
\r
1589 s = s.Remove (0, 1);
\r
1590 int parentheses = 0;
\r
1591 for (int i = 0; i < s.Length; i++) {
\r
1593 if (s [i] == '\'')
\r
1594 inString = !inString;
\r
1595 else if (s [i] == '(')
\r
1597 else if (s [i] == ')')
\r
1601 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1602 (s [i] == ')' && i == (s.Length -1))) { // Parameter changed
\r
1605 p1 = s.Substring (0, i);
\r
1606 s = s.Substring (i + 1);
\r
1610 else if (p2 == null) {
\r
1611 p2 = s.Substring (0, i);
\r
1612 s = s.Substring (i + 1);
\r
1616 else if (p3 == null) {
\r
1617 p3 = s.Substring (0, i);
\r
1618 s = s.Substring (i + 1);
\r
1623 throw new Exception (); // FIXME: What exception
\r
1627 if (p1 == null || p2 == null)
\r
1628 throw new Exception ();
\r
1630 ParseExpression (p1);
\r
1631 ParseExpression (p2);
\r
1632 ParseExpression (p3);
\r
1637 /// Class for In (exp, exp, exp, ...) function
\r
1639 internal class ExpressionIn : ExpressionElement
\r
1641 public ExpressionIn (string exp1, string exp2)
\r
1643 ParseExpression(exp1);
\r
1644 ParseParameters (exp2);
\r
1648 /// IsNull function does not return boolean value, so throw exception
\r
1650 public override bool Test (DataRow Row)
\r
1652 ExpressionElement E;
\r
1653 ExpressionElement columnElement = (ExpressionElement)Elements [0];
\r
1655 for (int i = 1; i < Elements.Count; i++)
\r
1657 E = (ExpressionElement)Elements [i];
\r
1658 if(ExpressionElement.Compare (columnElement, E, Row) == 0)
\r
1665 /// Parses parameters of function and invoke ParseExpression methods
\r
1667 private void ParseParameters (string s)
\r
1669 bool inString = false;
\r
1670 ArrayList parameters = new ArrayList();
\r
1673 while (!s.StartsWith ("("))
\r
1674 s = s.Remove (0, 1);
\r
1677 s = s.Remove (0, 1);
\r
1678 int parentheses = 0;
\r
1679 for (int i = 0; i < s.Length; i++)
\r
1682 if (s [i] == '\'')
\r
1683 inString = !inString;
\r
1684 else if (s [i] == '(')
\r
1686 else if (s [i] == ')')
\r
1690 if ((s [i] == ',' && !inString && parentheses == 0) ||
\r
1691 (s [i] == ')' && i == (s.Length -1)))
\r
1693 parameters.Add(s.Substring (0, i));
\r
1694 s = s.Substring (i + 1);
\r
1699 for (int i = 0; i < parameters.Count; i++)
\r
1700 ParseExpression((string)parameters[i]);
\r
1705 /// Class for just one element for example string, int, ...
\r
1707 internal class ExpressionSingleElement : ExpressionElement
\r
1709 private object Element = null;
\r
1711 public ExpressionSingleElement (string s)
\r
1713 // TODO: Every type should be checked
\r
1714 if (s.StartsWith ("'") && s.EndsWith ("'")) {
\r
1715 Element = s.Substring (1, s.Length - 2);
\r
1716 _ResultType = typeof (string);
\r
1718 else if (!Char.IsDigit (s [0]) && s [0] != '-' && s [0] != '+') {
\r
1720 _ResultType = typeof (DataColumn);
\r
1722 else if (s.StartsWith ("#") && s.EndsWith ("#")) {
\r
1723 Element = DateTime.Parse (s.Substring (1, s.Length - 2));
\r
1724 _ResultType = typeof (DateTime);
\r
1728 Element = int.Parse (s);
\r
1729 _ResultType = typeof (int);
\r
1731 Element = Decimal.Parse (s);
\r
1732 _ResultType = typeof (Decimal);
\r
1737 public override object Result (DataRow Row)
\r
1739 object Result = null;
\r
1740 if (ResultType (Row) == typeof (DataColumn)) {
\r
1742 if (!Row.Table.Columns.Contains (Element.ToString ()))
\r
1743 throw new EvaluateException ("Column name '" + Element.ToString () + "' not found.");
\r
1746 DataRowVersion rowVersion = DataRowVersion.Default;
\r
1747 // if this row is deleted we get the original version, or else we get an exception.
\r
1748 if (Row.RowState == DataRowState.Deleted)
\r
1749 rowVersion = DataRowVersion.Original;
\r
1750 Result = Row [Element.ToString (), rowVersion];
\r
1759 public override bool Test (DataRow Row)
\r
1761 throw new EvaluateException ();
\r
1766 /// Parent class of all the elements of expression
\r
1768 internal abstract class ExpressionElement
\r
1771 // TODO/FIXME: This class should be inherited more than once. I mean own subclass for operators, functions,...
\r
1774 protected string exp1;
\r
1775 protected string exp2;
\r
1776 protected Type _ResultType;
\r
1778 protected ArrayList Elements = new ArrayList ();
\r
1780 enum AGGREGATE {SUM, AVG, MIN, MAX, COUNT, STDEV, VAR}
\r
1781 //protected ArrayList Singles = new ArrayList ();
\r
1784 /// Tells does the current expressions match to current DataRow
\r
1786 abstract public bool Test (DataRow Row);
\r
1788 public virtual object Result (DataRow Row) {return null;}
\r
1790 public virtual Type ResultType (DataRow Row)
\r
1792 return _ResultType;
\r
1795 protected object CalculateResult (DataRow Row)
\r
1797 ExpressionElement E1 = ((ExpressionElement)Elements [0]);
\r
1798 ExpressionElement E2 = ((ExpressionElement)Elements [1]);
\r
1799 object Result = null;
\r
1800 object value1 = E1.Result (Row);
\r
1801 object value2 = E2.Result (Row);
\r
1802 Type t1 = value1.GetType ();
\r
1803 Type t2 = value2.GetType ();
\r
1806 if (value1 == DBNull.Value && value2 == DBNull.Value)
\r
1809 // TODO: More types
\r
1811 if (t1 == typeof (string) || t2 == typeof (string)) {
\r
1813 if (t1 != typeof (string))
\r
1814 value1 = Convert.ChangeType (value1, Type.GetTypeCode (t2));
\r
1815 else if (t2 != typeof (string))
\r
1816 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1820 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1822 Result = Calculate (value1, value2, t1);
\r
1826 protected virtual object Calculate (object value1, object value2, Type TempType)
\r
1832 /// static method for comparing two ExpressionElement. This is used in =, <, >, <>, <=, >= elements.
\r
1833 /// If elements are equal returns 0, if E1 is less that E2, return -1 else if E1 is greater 1
\r
1835 protected static int Compare (ExpressionElement E1, ExpressionElement E2, DataRow Row)
\r
1837 int ReturnValue = 0;
\r
1839 object value1 = E1.Result (Row);
\r
1840 object value2 = E2.Result (Row);
\r
1842 if ((value1 == null || value1 == DBNull.Value) && (value2 == null || value2 == DBNull.Value))
\r
1844 else if (value2 == null || value2 == DBNull.Value)
\r
1846 else if (value1 == null || value1 == DBNull.Value)
\r
1849 Type t1 = value1.GetType ();
\r
1850 Type t2 = value2.GetType ();
\r
1852 Type RT1 = E1.ResultType (Row);
\r
1853 Type RT2 = E2.ResultType (Row);
\r
1855 if (t1 == typeof (string) || t2 == typeof (string)) {
\r
1856 // FIXME: If one of elements are string they both should be???
\r
1857 //TempType = typeof (string);
\r
1858 if (t1 != typeof (string))
\r
1859 value1 = Convert.ChangeType (value1, Type.GetTypeCode (t2));
\r
1860 else if (t2 != typeof (string))
\r
1861 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1864 if (!Row.Table.CaseSensitive) {
\r
1865 value1 = ((string)value1).ToLower ();
\r
1866 value2 = ((string)value2).ToLower ();
\r
1868 }else if (t1 != t2) {
\r
1870 value2 = Convert.ChangeType (value2, Type.GetTypeCode (t1));
\r
1873 object Result = t1.InvokeMember ("CompareTo", BindingFlags.Default |
\r
1874 BindingFlags.InvokeMethod, null,
\r
1876 new object [] {value2});
\r
1877 ReturnValue = (int)Result;
\r
1879 return ReturnValue;
\r
1883 /// Finds and creates Expression elements.
\r
1884 /// This presumes that expression is valid.
\r
1886 protected void ParseExpression (string s)
\r
1889 // TODO/FIXME: IMHO, this should be done with different kind of parsing:
\r
1890 // char by char not operand by operand.
\r
1893 string inside = ""; // stores string betwee parentheses like a = 12 and (b = 1 or b = 2)
\r
1894 string function = ""; // stores fuction paramters like substring (this, are, paramters)
\r
1899 // Find parenthesis
\r
1900 if ((temp = s.IndexOf ("(")) != -1) {
\r
1902 string functionName = "";
\r
1903 while (temp != 0 && s [temp - 1] != '=')
\r
1906 // Get the previous element of expression
\r
1907 while (s [temp] != '(') {
\r
1908 char c = s [temp];
\r
1909 functionName = functionName + c;
\r
1913 functionName = functionName.Trim ();
\r
1914 functionName = functionName.ToLower ();
\r
1916 // check if previous element is a function
\r
1917 if (!functionName.EndsWith ("convert") && !functionName.EndsWith ("len") &&
\r
1918 !functionName.EndsWith ("isnull") && !functionName.EndsWith ("iif") &&
\r
1919 !functionName.EndsWith ("trim") && !functionName.EndsWith ("substring") &&
\r
1920 !functionName.EndsWith ("sum") && !functionName.EndsWith ("avg") &&
\r
1921 !functionName.EndsWith ("min") && !functionName.EndsWith ("max") &&
\r
1922 !functionName.EndsWith ("count") && !functionName.EndsWith ("stdev") &&
\r
1923 !functionName.EndsWith ("var")&& !functionName.EndsWith ("in")) {
\r
1925 int startIndex = s.IndexOf ("(");
\r
1926 int i = startIndex + 1;
\r
1942 s = s.Remove (startIndex, i - startIndex);
\r
1947 string string1 = null;
\r
1948 string string2 = null;
\r
1949 if (FindOrElement (s, ref string1, ref string2))
\r
1950 CreateOrElement (string1, string2, inside);
\r
1952 else if (FindAndElement (s, ref string1, ref string2))
\r
1953 CreateAndElement (string1, string2, inside);
\r
1956 else if (FindLikeElement (s, ref string1, ref string2))
\r
1957 CreateLikeElement (string1, string2, inside);
\r
1960 else if (FindInElement (s, ref string1, ref string2))
\r
1961 CreateInElement (string1, string2, inside);
\r
1964 else if (FindEqualElement (s, ref string1, ref string2))
\r
1965 CreateEqualsElement (string1, string2, inside);
\r
1968 else if (FindUnequalElement (s, ref string1, ref string2))
\r
1969 CreateUnequalsElement (string1, string2, inside);
\r
1972 else if (FindLessThanOrEqualElement (s, ref string1, ref string2))
\r
1973 CreateLessThanOrEqualElement (string1, string2, inside);
\r
1976 else if (FindLessThanElement (s, ref string1, ref string2))
\r
1977 CreateLessThanElement (string1, string2, inside);
\r
1980 else if (FindGreaterThanOrEqualElement (s, ref string1, ref string2))
\r
1981 CreateGreaterThanOrEqualElement (string1, string2, inside);
\r
1984 else if (FindGreaterThanElement (s, ref string1, ref string2))
\r
1985 CreateGreaterThanElement (string1, string2, inside);
\r
1987 // if there wasn't any operators like 'and' or 'not' there still could be
\r
1988 // arithmetic operators like '+' or '-' or functions like 'iif' or 'substring'
\r
1991 else if (FindMultiplyElement (s, ref string1, ref string2))
\r
1992 CreateMultiplyElement (string1, string2, inside);
\r
1995 else if (FindDivideElement (s, ref string1, ref string2))
\r
1996 CreateDivideElement (string1, string2, inside);
\r
2000 else if (FindAdditionElement (s, ref string1, ref string2))
\r
2001 CreateAdditionElement (string1, string2, inside);
\r
2004 else if (FindSubtractElement (s, ref string1, ref string2))
\r
2005 CreateSubtractionElement (string1, string2, inside);
\r
2008 else if (FindModulusElement (s, ref string1, ref string2))
\r
2009 CreateModulusElement (string1, string2, inside);
\r
2012 else if (FindAggregateElement (s, AGGREGATE.SUM))
\r
2013 Elements.Add (new ExpressionSum (s.Trim ()));
\r
2016 else if (FindAggregateElement (s, AGGREGATE.AVG))
\r
2017 Elements.Add (new ExpressionAvg (s.Trim ()));
\r
2020 else if (FindAggregateElement (s, AGGREGATE.MIN))
\r
2021 Elements.Add (new ExpressionMin (s.Trim ()));
\r
2024 else if (FindAggregateElement (s, AGGREGATE.MAX))
\r
2025 Elements.Add (new ExpressionMax (s.Trim ()));
\r
2028 else if (FindAggregateElement (s, AGGREGATE.COUNT))
\r
2029 Elements.Add (new ExpressionCount (s.Trim ()));
\r
2032 else if (FindAggregateElement (s, AGGREGATE.STDEV))
\r
2033 Elements.Add (new ExpressionStdev (s.Trim ()));
\r
2036 else if (FindAggregateElement (s, AGGREGATE.VAR))
\r
2037 Elements.Add (new ExpressionVar (s.Trim ()));
\r
2040 else if (FindLenElement (s))
\r
2041 Elements.Add (new ExpressionLen (s.Trim ()));
\r
2044 else if (FindIifElement (s))
\r
2045 Elements.Add (new ExpressionIif (s.Trim ()));
\r
2048 else if (FindIsNullElement (s))
\r
2049 Elements.Add (new ExpressionIsNull (s.Trim ()));
\r
2052 else if (FindSubstringElement (s))
\r
2053 Elements.Add (new ExpressionSubstring (s.Trim ()));
\r
2055 // if expression is like '(something someoperator something)'
\r
2056 else if (inside.Trim () != string.Empty)
\r
2057 ParseExpression (inside);
\r
2059 // At least, if it wasnt any of the above it is just normat string or int
\r
2062 Elements.Add (new ExpressionSingleElement (s.Trim ()));
\r
2065 #region CheckElement methods
\r
2068 // These methods are temporary for now
\r
2071 private bool FindOrElement (string s, ref string s1, ref string s2)
\r
2073 string stemp = s.ToLower ();
\r
2074 int indexOf = stemp.IndexOf("or");
\r
2076 if (indexOf == -1)
\r
2079 // Test if or is between ''
\r
2080 int oldIndex = -1;
\r
2081 while ((indexOf = stemp.IndexOf ("or", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2083 oldIndex = indexOf;
\r
2085 // check is the 'or' element part of string element
\r
2086 if (IsPartOfStringElement (stemp, indexOf))
\r
2089 // Check is or part of something else for example column name
\r
2090 if (indexOf != 0) {
\r
2092 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
2096 if (indexOf < s.Length + 2) {
\r
2098 if (stemp [indexOf + 2] != ' ' && stemp [indexOf + 2] != '\'')
\r
2102 if (IsPartOfFunction (stemp, indexOf))
\r
2105 s1 = s.Substring (0, indexOf).Trim ();
\r
2106 s2 = s.Substring (indexOf + 2).Trim ();
\r
2114 private bool FindAndElement (string s, ref string s1, ref string s2)
\r
2116 string stemp = s.ToLower ();
\r
2117 int indexOf = stemp.IndexOf("and");
\r
2119 if (indexOf == -1)
\r
2122 // Test if or is between ''
\r
2123 int oldIndex = -1;
\r
2124 while ((indexOf = stemp.IndexOf ("and", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2126 oldIndex = indexOf;
\r
2128 // check is the 'and' element part of string element
\r
2129 if (IsPartOfStringElement (stemp, indexOf))
\r
2133 // Check is or part of something else for example column name
\r
2134 if (indexOf != 0) {
\r
2136 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
2140 if (indexOf < stemp.Length + 3) {
\r
2142 if (stemp [indexOf + 3] != ' ' && stemp [indexOf + 3] != '\'')
\r
2146 if (IsPartOfFunction (stemp, indexOf))
\r
2150 s1 = s.Substring (0, indexOf).Trim ();
\r
2151 s2 = s.Substring (indexOf + 3).Trim ();
\r
2158 private bool FindLikeElement (string s, ref string s1, ref string s2)
\r
2160 string stemp = s.ToLower ();
\r
2161 int indexOf = stemp.IndexOf("like");
\r
2163 if (indexOf == -1)
\r
2166 // Test if or is between ''
\r
2167 int oldIndex = -1;
\r
2168 while ((indexOf = stemp.IndexOf ("like", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2170 oldIndex = indexOf;
\r
2172 // check is the 'and' element part of string element
\r
2173 if (IsPartOfStringElement (stemp, indexOf))
\r
2177 // Check is or part of something else for example column name
\r
2178 if (indexOf != 0) {
\r
2180 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
2184 if (indexOf < stemp.Length + 4) {
\r
2186 if (stemp [indexOf + 4] != ' ' && stemp [indexOf + 4] != '\'')
\r
2190 if (IsPartOfFunction (stemp, indexOf))
\r
2194 s1 = s.Substring (0, indexOf).Trim ();
\r
2195 s2 = s.Substring (indexOf + 4).Trim ();
\r
2202 private bool FindEqualElement (string s, ref string s1, ref string s2)
\r
2204 string stemp = s.ToLower ();
\r
2205 int indexOf = stemp.IndexOf ("=");
\r
2207 if (indexOf == -1)
\r
2210 int oldIndex = -1;
\r
2212 while ((indexOf = stemp.IndexOf ("=", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2214 oldIndex = indexOf;
\r
2216 // Check is the = part of <= or >=
\r
2217 if (stemp [indexOf - 1] == '<' || stemp [indexOf - 1] == '>')
\r
2220 // Check is the = element part of string element
\r
2221 if (IsPartOfStringElement (stemp, indexOf))
\r
2224 // Check is or part of column name
\r
2225 if (IsPartOfColumnName (stemp, indexOf))
\r
2228 if (IsPartOfFunction (stemp, indexOf))
\r
2231 s1 = s.Substring (0, indexOf).Trim ();
\r
2232 s2 = s.Substring (indexOf + 1).Trim ();
\r
2240 private bool FindUnequalElement (string s, ref string s1, ref string s2)
\r
2242 string stemp = s.ToLower ();
\r
2243 int indexOf = stemp.IndexOf ("<>");
\r
2245 if (stemp.IndexOf ("<>") == -1)
\r
2248 int oldIndex = -1;
\r
2249 while ((indexOf = stemp.IndexOf ("<>", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2251 oldIndex = indexOf;
\r
2253 // test if next charachter is something else than ' '
\r
2254 bool failed = false;
\r
2256 // Check is the <> element part of string element
\r
2257 if (IsPartOfStringElement (stemp, indexOf))
\r
2260 // Check is or part of column name
\r
2261 if (IsPartOfColumnName (stemp, indexOf))
\r
2264 if (IsPartOfFunction (stemp, indexOf))
\r
2267 s1 = s.Substring (0, indexOf).Trim ();
\r
2268 s2 = s.Substring (indexOf + 2).Trim ();
\r
2278 private bool FindLessThanElement (string s, ref string s1, ref string s2)
\r
2280 string stemp = s.ToLower ();
\r
2281 int indexOf = stemp.IndexOf ("<");
\r
2283 if (indexOf == -1)
\r
2286 int oldIndex = -1;
\r
2287 while ((indexOf = stemp.IndexOf ("<", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2289 oldIndex = indexOf;
\r
2291 // if < is part of <> or <=
\r
2292 if (stemp [indexOf + 1] == '>' || stemp [indexOf + 1] == '=')
\r
2295 // Test is < element part of string element
\r
2296 if (IsPartOfStringElement (stemp, indexOf))
\r
2299 // Check is or part of column name
\r
2300 if (IsPartOfColumnName (stemp, indexOf))
\r
2303 if (IsPartOfFunction (stemp, indexOf))
\r
2306 s1 = s.Substring (0, indexOf).Trim ();
\r
2307 s2 = s.Substring (indexOf + 1).Trim ();
\r
2315 private bool FindLessThanOrEqualElement (string s, ref string s1, ref string s2)
\r
2317 string stemp = s.ToLower ();
\r
2318 int indexOf = stemp.IndexOf ("<=");
\r
2320 if (indexOf == -1)
\r
2323 int oldIndex = -1;
\r
2324 while ((indexOf = stemp.IndexOf ("<=", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2326 oldIndex = indexOf;
\r
2327 // Test is <= element part of string element
\r
2328 if (IsPartOfStringElement (stemp, indexOf))
\r
2331 // Check is or part of column name
\r
2332 if (IsPartOfColumnName (stemp, indexOf))
\r
2335 if (IsPartOfFunction (stemp, indexOf))
\r
2338 s1 = s.Substring (0, indexOf).Trim ();
\r
2339 s2 = s.Substring (indexOf + 2).Trim ();
\r
2347 private bool FindGreaterThanElement (string s, ref string s1, ref string s2)
\r
2349 string stemp = s.ToLower ();
\r
2350 int indexOf = stemp.IndexOf (">");
\r
2352 if (indexOf == -1)
\r
2355 int oldIndex = -1;
\r
2356 while ((indexOf = stemp.IndexOf (">", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2358 oldIndex = indexOf;
\r
2360 // if < is part of <> or <=
\r
2361 if (stemp [indexOf - 1] == '<' || stemp [indexOf + 1] == '=')
\r
2364 // Test is < element part of string element
\r
2365 if (IsPartOfStringElement (stemp, indexOf))
\r
2368 // Check is or part of column name
\r
2369 if (IsPartOfColumnName (stemp, indexOf))
\r
2372 if (IsPartOfFunction (stemp, indexOf))
\r
2375 s1 = s.Substring (0, indexOf).Trim ();
\r
2376 s2 = s.Substring (indexOf + 1).Trim ();
\r
2383 private bool FindGreaterThanOrEqualElement (string s, ref string s1, ref string s2)
\r
2385 string stemp = s.ToLower ();
\r
2386 int indexOf = stemp.IndexOf (">=");
\r
2388 if (indexOf == -1)
\r
2391 int oldIndex = -1;
\r
2392 while ((indexOf = stemp.IndexOf (">=", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2394 oldIndex = indexOf;
\r
2395 bool failed = false;
\r
2396 // Test is <= element part of string element
\r
2398 // Check is or part of column name
\r
2399 if (IsPartOfColumnName (stemp, indexOf))
\r
2402 // is the element part of string element
\r
2403 if (IsPartOfStringElement (stemp, indexOf))
\r
2406 if (IsPartOfFunction (stemp, indexOf))
\r
2409 s1 = s.Substring (0, indexOf).Trim ();
\r
2410 s2 = s.Substring (indexOf + 2).Trim ();
\r
2418 private bool FindAdditionElement (string s, ref string s1, ref string s2)
\r
2420 string stemp = s.ToLower ();
\r
2421 int indexOf = stemp.IndexOf ("+");
\r
2423 if (indexOf == -1)
\r
2426 int oldIndex = -1;
\r
2427 while ((indexOf = stemp.IndexOf ("+", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2429 // FIXME: if '+' represents sign of integer
\r
2431 oldIndex = indexOf;
\r
2432 bool failed = false;
\r
2434 // Check is or part of column name
\r
2435 if (IsPartOfColumnName (stemp, indexOf))
\r
2438 // is the element part of string element
\r
2439 if (IsPartOfStringElement (stemp, indexOf))
\r
2442 if (IsPartOfFunction (stemp, indexOf))
\r
2445 s1 = s.Substring (0, indexOf).Trim ();
\r
2446 s2 = s.Substring (indexOf + 1).Trim ();
\r
2454 private bool FindSubtractElement (string s, ref string s1, ref string s2)
\r
2456 string stemp = s.ToLower ();
\r
2457 int indexOf = stemp.IndexOf ("-");
\r
2459 if (indexOf == -1)
\r
2462 int oldIndex = -1;
\r
2463 while ((indexOf = stemp.IndexOf ("-", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2465 oldIndex = indexOf;
\r
2466 bool failed = false;
\r
2468 // check is this lonely element
\r
2470 for (int i = indexOf - 1; i >= 0; i--) {
\r
2471 if (stemp [i] != ' ') {
\r
2480 // Check is or part of column name
\r
2481 if (IsPartOfColumnName (stemp, indexOf))
\r
2484 // is the element part of string element
\r
2485 if (IsPartOfStringElement (stemp, indexOf))
\r
2488 if (IsPartOfFunction (stemp, indexOf))
\r
2491 s1 = s.Substring (0, indexOf).Trim ();
\r
2492 s2 = s.Substring (indexOf + 1).Trim ();
\r
2500 private bool FindMultiplyElement (string s, ref string s1, ref string s2)
\r
2502 string stemp = s.ToLower ();
\r
2503 int indexOf = stemp.IndexOf ("*");
\r
2505 if (indexOf == -1)
\r
2508 int oldIndex = -1;
\r
2509 while ((indexOf = stemp.IndexOf ("*", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2512 oldIndex = indexOf;
\r
2513 bool failed = false;
\r
2515 // FIXME: If there is a divide operator before multiply operator.
\r
2517 // Check is or part of column name
\r
2518 if (IsPartOfColumnName (stemp, indexOf))
\r
2521 // is the element part of string element
\r
2522 if (IsPartOfStringElement (stemp, indexOf))
\r
2525 if (IsPartOfFunction (stemp, indexOf))
\r
2528 s1 = s.Substring (0, indexOf).Trim ();
\r
2529 s2 = s.Substring (indexOf + 1).Trim ();
\r
2537 private bool FindDivideElement (string s, ref string s1, ref string s2)
\r
2539 string stemp = s.ToLower ();
\r
2540 int indexOf = stemp.IndexOf ("/");
\r
2542 if (indexOf == -1)
\r
2545 int oldIndex = -1;
\r
2546 while ((indexOf = stemp.IndexOf ("/", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2549 oldIndex = indexOf;
\r
2550 bool failed = false;
\r
2552 // FIXME: If there is a multiply operator before divide operator.
\r
2554 // Check is or part of column name
\r
2555 if (IsPartOfColumnName (stemp, indexOf))
\r
2558 // is the element part of string element
\r
2559 if (IsPartOfStringElement (stemp, indexOf))
\r
2562 if (IsPartOfFunction (stemp, indexOf))
\r
2565 s1 = s.Substring (0, indexOf).Trim ();
\r
2566 s2 = s.Substring (indexOf + 1).Trim ();
\r
2574 private bool FindModulusElement (string s, ref string s1, ref string s2)
\r
2576 string stemp = s.ToLower ();
\r
2577 int indexOf = stemp.IndexOf ("%");
\r
2579 if (indexOf == -1)
\r
2582 int oldIndex = -1;
\r
2583 while ((indexOf = stemp.IndexOf ("%", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2586 oldIndex = indexOf;
\r
2587 bool failed = false;
\r
2589 // FIXME: If there is a multiply operator before divide operator.
\r
2591 // Check is or part of column name
\r
2592 if (IsPartOfColumnName (stemp, indexOf))
\r
2595 // is the element part of string element
\r
2596 if (IsPartOfStringElement (stemp, indexOf))
\r
2599 s1 = s.Substring (0, indexOf).Trim ();
\r
2600 s2 = s.Substring (indexOf + 1).Trim ();
\r
2608 private bool FindAggregateElement (string s, AGGREGATE aggregate)
\r
2610 string agg = null;
\r
2612 switch (aggregate) {
\r
2614 case AGGREGATE.SUM:
\r
2617 case AGGREGATE.AVG:
\r
2620 case AGGREGATE.MIN:
\r
2623 case AGGREGATE.MAX:
\r
2626 case AGGREGATE.COUNT:
\r
2629 case AGGREGATE.STDEV:
\r
2632 case AGGREGATE.VAR:
\r
2636 throw new NotImplementedException ();
\r
2640 string stemp = s.ToLower ();
\r
2641 int indexOf = stemp.IndexOf (agg);
\r
2643 if (indexOf == -1)
\r
2646 int oldIndex = -1;
\r
2647 while ((indexOf = stemp.IndexOf (agg, oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2649 oldIndex = indexOf;
\r
2650 bool failed = false;
\r
2652 // Check is or part of column name
\r
2653 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2656 // is the element part of string element
\r
2657 if (IsPartOfStringElement (stemp, indexOf))
\r
2668 private bool FindSumElement (string s)
\r
2670 string stemp = s.ToLower ();
\r
2671 int indexOf = stemp.IndexOf ("sum");
\r
2673 if (indexOf == -1)
\r
2676 int oldIndex = -1;
\r
2677 while ((indexOf = stemp.IndexOf ("sum", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2679 oldIndex = indexOf;
\r
2680 bool failed = false;
\r
2682 // Check is or part of column name
\r
2683 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2686 // is the element part of string element
\r
2687 if (IsPartOfStringElement (stemp, indexOf))
\r
2697 private bool FindAvgElement (string s)
\r
2699 string stemp = s.ToLower ();
\r
2700 int indexOf = stemp.IndexOf ("avg");
\r
2702 if (indexOf == -1)
\r
2705 int oldIndex = -1;
\r
2706 while ((indexOf = stemp.IndexOf ("avg", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2708 oldIndex = indexOf;
\r
2709 bool failed = false;
\r
2711 // Check is or part of column name
\r
2712 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2715 // is the element part of string element
\r
2716 if (IsPartOfStringElement (stemp, indexOf))
\r
2725 private bool FindMinElement (string s)
\r
2727 string stemp = s.ToLower ();
\r
2728 int indexOf = stemp.IndexOf ("min");
\r
2730 if (indexOf == -1)
\r
2733 int oldIndex = -1;
\r
2734 while ((indexOf = stemp.IndexOf ("min", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2736 oldIndex = indexOf;
\r
2737 bool failed = false;
\r
2739 // Check is or part of column name
\r
2740 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2743 // is the element part of string element
\r
2744 if (IsPartOfStringElement (stemp, indexOf))
\r
2753 private bool FindMaxElement (string s)
\r
2755 string stemp = s.ToLower ();
\r
2756 int indexOf = stemp.IndexOf ("max");
\r
2758 if (indexOf == -1)
\r
2761 int oldIndex = -1;
\r
2762 while ((indexOf = stemp.IndexOf ("max", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2764 oldIndex = indexOf;
\r
2765 bool failed = false;
\r
2767 // Check is or part of column name
\r
2768 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2771 // is the element part of string element
\r
2772 if (IsPartOfStringElement (stemp, indexOf))
\r
2781 private bool FindCountElement (string s)
\r
2783 string stemp = s.ToLower ();
\r
2784 int indexOf = stemp.IndexOf ("count");
\r
2786 if (indexOf == -1)
\r
2789 int oldIndex = -1;
\r
2790 while ((indexOf = stemp.IndexOf ("count", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2792 oldIndex = indexOf;
\r
2793 bool failed = false;
\r
2795 // Check is or part of column name
\r
2796 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2799 // is the element part of string element
\r
2800 if (IsPartOfStringElement (stemp, indexOf))
\r
2809 private bool FindStdevElement (string s)
\r
2811 string stemp = s.ToLower ();
\r
2812 int indexOf = stemp.IndexOf ("stdev");
\r
2814 if (indexOf == -1)
\r
2817 int oldIndex = -1;
\r
2818 while ((indexOf = stemp.IndexOf ("stdev", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2820 oldIndex = indexOf;
\r
2821 bool failed = false;
\r
2823 // Check is or part of column name
\r
2824 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2827 // is the element part of string element
\r
2828 if (IsPartOfStringElement (stemp, indexOf))
\r
2837 private bool FindVarElement (string s)
\r
2839 string stemp = s.ToLower ();
\r
2840 int indexOf = stemp.IndexOf ("var");
\r
2842 if (indexOf == -1)
\r
2845 int oldIndex = -1;
\r
2846 while ((indexOf = stemp.IndexOf ("var", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2848 oldIndex = indexOf;
\r
2849 bool failed = false;
\r
2851 // Check is or part of column name
\r
2852 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2855 // is the element part of string element
\r
2856 if (IsPartOfStringElement (stemp, indexOf))
\r
2865 private bool FindLenElement (string s)
\r
2867 string stemp = s.ToLower ();
\r
2868 int indexOf = stemp.IndexOf ("len");
\r
2870 if (indexOf == -1)
\r
2873 int oldIndex = -1;
\r
2874 while ((indexOf = stemp.IndexOf ("len", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2876 oldIndex = indexOf;
\r
2877 bool failed = false;
\r
2879 // Check is or part of column name
\r
2880 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2883 // is the element part of string element
\r
2884 if (IsPartOfStringElement (stemp, indexOf))
\r
2894 private bool FindIifElement (string s)
\r
2896 string stemp = s.ToLower ();
\r
2897 int indexOf = stemp.IndexOf ("iif");
\r
2899 if (indexOf == -1)
\r
2902 int oldIndex = -1;
\r
2903 while ((indexOf = stemp.IndexOf ("iif", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2905 oldIndex = indexOf;
\r
2906 bool failed = false;
\r
2908 // Check is or part of column name
\r
2909 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2912 // is the element part of string element
\r
2913 if (IsPartOfStringElement (stemp, indexOf))
\r
2922 private bool FindIsNullElement (string s)
\r
2924 string stemp = s.ToLower ();
\r
2925 int indexOf = stemp.IndexOf ("isnull");
\r
2927 if (indexOf == -1)
\r
2930 int oldIndex = -1;
\r
2931 while ((indexOf = stemp.IndexOf ("isnull", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2933 oldIndex = indexOf;
\r
2934 bool failed = false;
\r
2936 // Check is or part of column name
\r
2937 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2940 // is the element part of string element
\r
2941 if (IsPartOfStringElement (stemp, indexOf))
\r
2950 private bool FindSubstringElement (string s)
\r
2952 string stemp = s.ToLower ();
\r
2953 int indexOf = stemp.IndexOf ("substring");
\r
2955 if (indexOf == -1)
\r
2958 int oldIndex = -1;
\r
2959 while ((indexOf = stemp.IndexOf ("substring", oldIndex + 1)) != -1 && indexOf > oldIndex) {
\r
2961 oldIndex = indexOf;
\r
2962 bool failed = false;
\r
2964 // Check is or part of column name
\r
2965 if (indexOf != 0 && stemp [indexOf - 1] != ' ')
\r
2968 // is the element part of string element
\r
2969 if (IsPartOfStringElement (stemp, indexOf))
\r
2978 private bool FindInElement (string s, ref string s1, ref string s2)
\r
2980 string stemp = s.ToLower ();
\r
2981 int indexOf = stemp.IndexOf ("in");
\r
2983 if (indexOf == -1)
\r
2986 int oldIndex = -1;
\r
2987 while ((indexOf = stemp.IndexOf ("in", oldIndex + 1)) != -1 && indexOf > oldIndex)
\r
2989 oldIndex = indexOf;
\r
2991 // check is the 'and' element part of string element
\r
2992 if (IsPartOfStringElement (stemp, indexOf))
\r
2996 // Check is or part of something else for example column name
\r
2997 if (indexOf != 0)
\r
2999 if (stemp [indexOf - 1] != ' ' && stemp [indexOf - 1] != '\'')
\r
3003 if (indexOf < stemp.Length + 2)
\r
3005 if (stemp [indexOf + 2] != ' ' && stemp [indexOf + 2] != '\'')
\r
3009 if (IsPartOfFunction (stemp, indexOf))
\r
3012 s1 = s.Substring (0, indexOf).Trim ();
\r
3013 s2 = s.Substring (indexOf + 2).Trim ();
\r
3021 #endregion // CheckElement methods
\r
3023 #region CreateElement methods
\r
3026 // These methods are going to be removed when way of parsing is changed
\r
3029 private void CreateOrElement (string s1, string s2, string inside)
\r
3031 CheckParenthesis (inside, ref s1, ref s2);
\r
3032 Elements.Add (new ExpressionOr (s1.Trim (), s2.Trim ()));
\r
3035 private void CreateAndElement (string s1, string s2, string inside)
\r
3037 CheckParenthesis (inside, ref s1, ref s2);
\r
3038 Elements.Add (new ExpressionAnd (s1.Trim (), s2.Trim ()));
\r
3041 private void CreateLikeElement (string s1, string s2, string inside)
\r
3043 CheckParenthesis (inside, ref s1, ref s2);
\r
3044 Elements.Add (new ExpressionLike (s1.Trim (), s2.Trim ()));
\r
3047 private void CreateInElement (string s1, string s2, string inside)
\r
3049 CheckParenthesis (inside, ref s1, ref s2);
\r
3050 Elements.Add (new ExpressionIn (s1.Trim (), s2.Trim ()));
\r
3053 private void CreateEqualsElement (string s1, string s2, string inside)
\r
3055 CheckParenthesis (inside, ref s1, ref s2);
\r
3056 Elements.Add (new ExpressionEquals (s1.Trim (), s2.Trim ()));
\r
3059 private void CreateUnequalsElement (string s1, string s2, string inside)
\r
3061 CheckParenthesis (inside, ref s1, ref s2);
\r
3062 Elements.Add (new ExpressionUnequals (s1.Trim (), s2.Trim ()));
\r
3065 private void CreateLessThanElement (string s1, string s2, string inside)
\r
3067 CheckParenthesis (inside, ref s1, ref s2);
\r
3068 Elements.Add (new ExpressionLessThan (s1.Trim (), s2.Trim ()));
\r
3071 private void CreateLessThanOrEqualElement (string s1, string s2, string inside)
\r
3073 CheckParenthesis (inside, ref s1, ref s2);
\r
3074 Elements.Add (new ExpressionLessThanOrEqual (s1.Trim (), s2.Trim ()));
\r
3077 private void CreateGreaterThanElement (string s1, string s2, string inside)
\r
3079 CheckParenthesis (inside, ref s1, ref s2);
\r
3080 Elements.Add (new ExpressionGreaterThan (s1.Trim (), s2.Trim ()));
\r
3084 private void CreateGreaterThanOrEqualElement (string s1, string s2, string inside)
\r
3086 CheckParenthesis (inside, ref s1, ref s2);
\r
3087 Elements.Add (new ExpressionGreaterThanOrEqual (s1.Trim (), s2.Trim ()));
\r
3090 private void CreateAdditionElement (string s1, string s2, string inside)
\r
3092 CheckParenthesis (inside, ref s1, ref s2);
\r
3093 Elements.Add (new ExpressionAddition (s1.Trim (), s2.Trim ()));
\r
3096 private void CreateSubtractionElement (string s1, string s2, string inside)
\r
3098 CheckParenthesis (inside, ref s1, ref s2);
\r
3099 Elements.Add (new ExpressionSubtraction (s1.Trim (), s2.Trim ()));
\r
3102 private void CreateMultiplyElement (string s1, string s2, string inside)
\r
3104 CheckParenthesis (inside, ref s1, ref s2);
\r
3105 Elements.Add (new ExpressionMultiply (s1.Trim (), s2.Trim ()));
\r
3108 private void CreateDivideElement (string s1, string s2, string inside)
\r
3110 CheckParenthesis (inside, ref s1, ref s2);
\r
3111 Elements.Add (new ExpressionDivide (s1.Trim (), s2.Trim ()));
\r
3114 private void CreateModulusElement (string s1, string s2, string inside)
\r
3116 CheckParenthesis (inside, ref s1, ref s2);
\r
3117 Elements.Add (new ExpressionModulus (s1.Trim (), s2.Trim ()));
\r
3120 #endregion // CreateElemnt methods
\r
3122 #region Little helppers
\r
3124 private void CheckParenthesis (string inside, ref string s1, ref string s2)
\r
3126 if (s1 == string.Empty && inside != string.Empty)
\r
3128 else if (s2 == string.Empty && inside != string.Empty)
\r
3134 /// Checks is the element part of stringelement
\r
3136 private bool IsPartOfStringElement (string s, int indexOf)
\r
3138 // count how many '-charachters are before or. If count is odd it means or IS between quotes
\r
3140 for (int i = indexOf - 1; i >= 0; i--) {
\r
3141 if (s [i] == '\'')
\r
3145 if (quotes % 2 != 0)
\r
3152 /// Checks is the element part of column table
\r
3154 private bool IsPartOfColumnName (string s, int indexOf)
\r
3156 for (int i = indexOf; i >= 0; i--) {
\r
3158 // If the element is between [] it is part of columnname
\r
3159 if (s [i] == '\'' || s [i] == ']') {
\r
3162 else if (s [i] == '[') {
\r
3172 /// Checks are element part of function
\r
3174 private bool IsPartOfFunction (string s, int indexOf)
\r
3178 // If ',' or '\'' comes before '(' this element is not part of function's parameters
\r
3181 for (int i = indexOf; i >= 0; i--) {
\r
3183 if (s [i] == '(' || s [i] == ',') {
\r
3186 else if (s [i] == ')') {
\r
3194 #endregion // Little helppers
\r