コード例 #1
0
ファイル: ObjectExpression.cs プロジェクト: Marceli/Roberta
 internal ObjectExpression(Type objectType, Expression expression, Mappings maps, int parameterCount)
 {
     _objectType = objectType;
     _expression = expression;
     _maps = maps;
     _parameterCount = parameterCount;
 }
コード例 #2
0
ファイル: Function.cs プロジェクト: Marceli/Roberta
        public Function(FunctionOperator op, Expression[] args)
        {
            if( op == FunctionOperator.Substring && args.Length == 2 )
            {
                Expression[] newArgs = new Expression[3];
                newArgs[0] = args[0];
                newArgs[1] = args[1];
                newArgs[2] = new Function(FunctionOperator.Len, new Expression[] {(Expression)args[0].Clone()});
                args = newArgs;
            }

            this.Operator = op;
            this.Params = args;
        }
コード例 #3
0
ファイル: OrderBy.cs プロジェクト: cnporras/wilsonormapper
		public OrderBy(Expression source, OrderByItemCollection orderByItems, OrderByJoinCollection orderByJoins)
		{
			this.Source = source;
			_items = orderByItems;
			_joins = orderByJoins;
		}
コード例 #4
0
ファイル: OPath.cs プロジェクト: cnporras/wilsonormapper
		private bool ValidateNode(Expression node, object[] noargs)
		{
			node.Validate();
			return true;
		}
コード例 #5
0
ファイル: Binary.cs プロジェクト: tomtangrx/wilsonormapper
		internal static Type GetResultType(Expression leftExpr, Expression rightExpr, BinaryOperator op)
		{
			if( IsOperatorBoolean(op) )
			{
				return typeof(bool);
			}

			if( op == BinaryOperator.Concatenation )
			{
				return typeof(string);
			}

			// if we make it here, we are deal with an Arithmetic operator

			//V2: the code below is a gross simplification or the actual logic that should be here truly deal with all the scenarios
			//    there is MUCH MUCH more to do here to fully implement this method.

			Type leftType = leftExpr.ValueType;
			Type rightType = rightExpr.ValueType;

			if( leftExpr.NodeType == NodeType.Parameter )
			{
				leftType = rightType; //V2: use inferredType?
			}
			else if( rightExpr.NodeType == NodeType.Parameter )
			{
				rightType = leftType; //V2: use inferredType?
			}

			// to simplify the logic convert char types to strings
			if( leftType == typeof(char) )
			{
				leftType = typeof(string);
			}
			if( rightType == typeof(char) )
			{
				rightType = typeof(string);
			}

			// a string combined with any other type equals a string
			if( leftType == typeof(string) || rightType == typeof(string) )
			{
				return typeof(string);
			}

			// a datetime combined with any other type equals a datetime
			if( leftType == typeof(DateTime) || rightType == typeof(DateTime) )
			{
				return typeof(DateTime);
			}

            // determine the precedence of the two types
			int leftIndex = GetPrecedenceIndex(leftType);
			int rightIndex = GetPrecedenceIndex(rightType);

			if( leftIndex == 0 || rightIndex == 0 )
			{
				//note: we should probably be throwing an error here
				return null;
			}

			// return the type with the higher precedence
			return (leftIndex >= rightIndex) ? leftType : rightType;
		}
コード例 #6
0
ファイル: OPath.cs プロジェクト: cnporras/wilsonormapper
		private bool ReplaceAxisCallback(Expression node, object[] noargs) // note: internal longhorn name found on www.winfx247.com
		{
			if( node.NodeType == NodeType.Axis )
			{
				Axis axis = (Axis)node;
				
				// convert the axis into a filter (don't want any axis nodes in final tree)
				Expression filter = new Filter(axis);

				// see if we need to wrap the filter with an exist node
				// note: this is needed when:
				//		1) the source property of the axis is relational
				//		2) the parent of the axis is not already an exists (for future support for the exists keyword)
				//		3) the axis is not in the source of its parent filter
				if( axis.Owner.NodeType != NodeType.Unary || ((Unary)axis.Owner).Operator != UnaryOperator.Exists )
				{
					// get the source property for this axis
					Property property;
					if( axis.Source.NodeType == NodeType.Property )
					{
						property = (Property)axis.Source;
					}
					else if( axis.Source.NodeType == NodeType.Filter || axis.Source.NodeType == NodeType.Axis )
					{
						property = (Property)(axis.Source as Filter).Source;
					}
					else // source not property, filter, or axis
					{
						throw new Exception("Axis source node type of '" + axis.Source.NodeType + "' was not expected.");
					}
				
					if( property.IsRelational )
					{
						// find the containing filter for this axis (there has to be one) and track the child
						Expression child = axis;
						Expression parent = axis.Owner;
						while( parent != null && parent.NodeType != NodeType.Filter )
						{
							child = parent;
							parent = parent.Owner;
						}
						if( parent == null )
						{
							throw new Exception("Axis node is not contained in a Filter node.  Assumption failed.");
						}
			
						if( ((Filter)parent).Source != child ) // axis not in source of filter
						{
							filter = new Unary(UnaryOperator.Exists, filter);
						}
					}
				}

				// do the replacement
				Expression.Replace(axis, filter);
			}
			return true;
		}
コード例 #7
0
ファイル: OPath.cs プロジェクト: cnporras/wilsonormapper
		private bool ReplaceAddWithConcatenation(Expression node, object[] noargs) // note: internal longhorn name found on www.winfx247.com
		{
			if( node.NodeType == NodeType.Binary )
			{
				Binary binary = (Binary)node;
				if( binary.Operator == BinaryOperator.Addition && binary.Left.ValueType == typeof(string) && binary.Right.ValueType == typeof(string) )
				{
					binary.Operator = BinaryOperator.Concatenation;
				}
			}
			return true;
		}
コード例 #8
0
ファイル: Expression.cs プロジェクト: Marceli/Roberta
        public static void EnumNodes(Expression root, EnumNodesCallBack callback, EnumNodesCallBack postCallback, params object[] args)
        {
            switch( root.NodeType )
            {
                case NodeType.Literal:
                case NodeType.Parameter:
                case NodeType.Context:
                {
                    if( callback != null )
                    {
                        callback(root, args);
                    }
                    if( postCallback != null )
                    {
                        postCallback(root, args);
                    }
                    return;
                }
                case NodeType.Binary:
                {
                    if( callback == null || callback(root, args) )
                    {
                        Binary node = (Binary)root;
                        Expression.EnumNodes(node.Left, callback, postCallback, args);
                        Expression.EnumNodes(node.Right, callback, postCallback, args);

                        if( postCallback != null )
                        {
                            postCallback(root, args);
                        }
                    }
                    return;
                }
                case NodeType.Unary:
                {
                    if( callback == null || callback(root, args) )
                    {
                        Unary node = (Unary)root;
                        Expression.EnumNodes(node.Operand, callback, postCallback, args);

                        if( postCallback != null )
                        {
                            postCallback(root, args);
                        }
                    }
                    return;
                }
                case NodeType.Axis:
                case NodeType.Filter:
                {
                    if( callback == null || callback(root, args) )
                    {
                        Filter node = (Filter)root;
                        Expression.EnumNodes(node.Source, callback, postCallback, args);
                        Expression.EnumNodes(node.Constraint, callback, postCallback, args);

                        if( postCallback != null )
                        {
                            postCallback(root, args);
                        }
                    }
                    return;
                }
                case NodeType.Property:
                {
                    if( callback == null || callback(root, args) )
                    {
                        Property node = (Property)root;
                        Expression.EnumNodes(node.Source, callback, postCallback, args);

                        if( postCallback != null )
                        {
                            postCallback(root, args);
                        }
                    }
                    return;
                }
                case NodeType.Parent:
                {
                    if( callback == null || callback(root, args) )
                    {
                        Parent node = (Parent)root;
                        Expression.EnumNodes(node.Source, callback, postCallback, args);

                        if( postCallback != null )
                        {
                            postCallback(root, args);
                        }
                    }
                    return;
                }
                case NodeType.Function:
                {
                    if( callback == null || callback(root, args) )
                    {
                        Function node = (Function)root;
                        for( int i = 0; i < node.Params.Length; i++ )
                        {
                            Expression.EnumNodes(node.Params[i], callback, postCallback, args);
                        }

                        if( postCallback != null )
                        {
                            postCallback(root, args);
                        }
                    }
                    return;
                }
                case NodeType.TypeFilter:
                {
                    if( callback == null || callback(root, args) )
                    {
                        TypeFilter node = (TypeFilter)root;
                        Expression.EnumNodes(node.Source, callback, postCallback, args);

                        if( postCallback != null )
                        {
                            postCallback(root, args);
                        }
                    }
                    return;
                }
                case NodeType.Empty:
                {
                    return;
                }
                case NodeType.OrderBy:
                {
                    if( callback == null || callback(root, args) )
                    {
                        OrderBy node = (OrderBy)root;
                        Expression.EnumNodes(node.Source, callback, postCallback, args);

                        if( postCallback != null )
                        {
                            postCallback(root, args);
                        }
                    }
                    return;
                }
                default:
                {
                    throw new NotSupportedException("Expression type '" + root.GetType() + "' is not currently supported.");
                }
            }
        }
コード例 #9
0
ファイル: OPath.cs プロジェクト: cnporras/wilsonormapper
		private bool RecomposeBinary(Expression node, object[] noargs) // note: internal longhorn name found on www.winfx247.com
		{
			if( node.NodeType == NodeType.Binary )
			{
				Binary binary = (Binary)node;

				bool leftIsAxis = (binary.Left.NodeType == NodeType.Axis);
				bool rightIsAxis = (binary.Right.NodeType == NodeType.Axis);

				// nothing to do if neither branch contains an axis
				if( !leftIsAxis && !rightIsAxis )
				{
					return true;
				}

				// don't consider moving the binary node if neither branch is constant (and joined by a logical operator)
				// the binary node should stay above an axis in this case (example: (AAA.BBB = X) && (CCC = Y))
				if( !binary.Left.IsConst && !binary.Right.IsConst && Binary.IsOperatorLogical(binary.Operator) )
				{
					return true;
				}

				// see if we have an axis on both sides
				if( leftIsAxis && rightIsAxis )
				{
					throw new NotSupportedException("Relationship traversals on both sides of a binary operator is not currently supported.");
					// recompose the left and right to put both under one axis
					//V2: Recompose2Axis(binary);
					//return true;
				}
				else // axis on one side only
				{
					// get our root axis and find the last (leaf) axis in the chain
					// the leaf axis will hold the parent binary when moved
					// (this is to handle multiple dot expressions like: AAA.BBB.CCC = @Value)
					Axis axis = (leftIsAxis) ? (Axis)binary.Left : (Axis)binary.Right;
					Axis leafAxis = axis;
					int parentCount = 1;
					while( leafAxis.Constraint.NodeType == NodeType.Axis )
					{
						leafAxis = (Axis)leafAxis.Constraint;
						parentCount += 1;
					}

					// now make the binary node the constraint of the the leaf axis
					//   and move the existing constraint under the other branch of the binary
					if( leftIsAxis )
					{
						Expression newRight = (Expression)binary.Right.Clone();
						Expression.EnumNodes(newRight, new Expression.EnumNodesCallBack(this.IncreaseParentDepth), null, parentCount);
						leafAxis.Constraint = new Binary(binary.Operator, leafAxis.Constraint, newRight);
					}
					else // right is axis
					{
						Expression newLeft = (Expression)binary.Left.Clone();
						Expression.EnumNodes(newLeft, new Expression.EnumNodesCallBack(this.IncreaseParentDepth), null, parentCount);
						leafAxis.Constraint = new Binary(binary.Operator, newLeft, leafAxis.Constraint);
					}

					Expression.Replace(binary, axis);
				}
			}

			return true;
		}
コード例 #10
0
ファイル: Filter.cs プロジェクト: cnporras/wilsonormapper
		public Filter(Expression source, Expression constraint)
		{
			this.Source = source;
			this.Constraint = constraint;
		}
コード例 #11
0
ファイル: Binary.cs プロジェクト: Marceli/Roberta
 public Binary(BinaryOperator op, Expression left, Expression right)
 {
     this.Operator = op;
     this.Left = left;
     this.Right = right;
 }
コード例 #12
0
		private void WriteSqlQuery(TextWriter w, Expression expr)
		{
			switch( expr.NodeType )
			{
				case NodeType.Property:
				{
					Property property = (Property)expr;
					
					EntityMap map = _maps[property.OwnerClass];
					FieldMap field = map.GetFieldMap(property.Name);
					if( field == null )
					{
						throw new Exception("Property '" + property.Name + "' could not be found for entity type '" + property.OwnerClass + "'.");
					}

					string alias;
					if( !field.IsLookup )
					{
						alias = GetAlias(property);
					}
					else // lookup field
					{
						LookupMap lookup = (LookupMap)field;
						alias = (string)_lookupFieldToAliasMap[lookup.FieldAlias];
					}
					if( alias == null )
					{
						throw new Exception("Could not find table alias for property '" + property.Name + "' in entity '" + property.OwnerClass + "'.");
					}

					WriteSqlColumn(w, alias, field.Field);
					return;
				}
				case NodeType.Parameter:
				{
					Query.Parameter node = (Query.Parameter)expr;

					string name;
					if( !_provider.NoNamedParameters )
					{
						name = _provider.ParameterPrefix + "P" + node.Ordinal;
					}
					else
					{
						name = "?";
					}

					_parameterTable.Add( new OPathParameter(name, node.ValueType) );
	
					w.Write(name);
					return;
				}
				case NodeType.Literal:
				{
					Literal node = (Literal)expr;
					WriteLiteral(w, node.Value);
					return;
				}
				case NodeType.Binary:
				{
					Binary node = (Binary)expr;

					bool isFormat;
					string keyword = GetSqlKeyword(node.Operator, out isFormat);

					if( isFormat )
					{
						WriteFormat(w, keyword, node.Left, node.Right);
					}
					else
					{
						w.Write('(');
						WriteSqlQuery(w, node.Left);
						w.Write(' ');
						w.Write(keyword);
						w.Write(' ');
						WriteSqlQuery(w, node.Right);
						w.Write(')');
					}
					return;
				}
				case NodeType.Unary:
				{
					Unary node = (Unary)expr;

					if( node.Operator == UnaryOperator.Exists )
					{
						w.Write(GetSqlKeyword(node.Operator));
						w.Write("\n(\n");
						WriteSqlQuery(w, node.Operand);
						w.Write("\n)");
					}
					else if( node.Operator == UnaryOperator.IsNull )
					{
						w.Write('(');
						WriteSqlQuery(w, node.Operand);
						w.Write(' ');
						w.Write(GetSqlKeyword(node.Operator));
						w.Write(')');
					}
					else
					{
						w.Write(GetSqlKeyword(node.Operator));
						w.Write('(');
						WriteSqlQuery(w, node.Operand);
						w.Write(')');
					}
					return;
				}
				case NodeType.Filter:
				{
					Filter filter = (Filter)expr;

					// the only supported filters are the root and ones directly below an exists node
					if( filter.Owner != null && (filter.Owner.NodeType != NodeType.Unary || (filter.Owner as Unary).Operator != UnaryOperator.Exists) )
					{
						throw new NotSupportedException("Filter with source type '" + filter.Source.NodeType + "' was not expected.");
					}

					EntityMap entity = _maps[filter.ValueType];
					string entityAlias = GetNextAlias();
					filter.Alias = entityAlias;

					bool whereStarted = false;
					if( filter.Source.NodeType == NodeType.TypeFilter ) // root filter/outer select
					{
						Join[] lookupJoins;
						WriteSelectClause(w, entity, entityAlias, out lookupJoins);

						Join[] joins;
						if( _orderByNode != null )
						{
							Join[] orderByJoins = GetJoinsFromOrderBy(entity, entityAlias, _orderByNode);
							joins = new Join[lookupJoins.Length + orderByJoins.Length];
							lookupJoins.CopyTo(joins, 0);
							orderByJoins.CopyTo(joins, lookupJoins.Length);
						}
						else
						{
							joins = lookupJoins;
						}

						WriteFromClause(w, entity.Table, entityAlias, joins);
						if( entity.BaseEntity != null )
						{
							WriteSubEntityConstraint(w, entityAlias, entity.TypeField, entity.TypeValue, ref whereStarted);
						}
						WriteFilterConstraints(w, filter, whereStarted);
						
						// add the default sort order if the entity has one defined but the query is not ordered
						if( _orderByNode == null && entity.SortOrder != null && entity.SortOrder.Length > 0 )
						{
							w.Write("\nORDER BY ");
							w.Write(entity.SortOrder);
						}
					}
					else if( filter.Source.NodeType == NodeType.Property || filter.Source.NodeType == NodeType.Filter ) // nested filter/subquery
					{
						Expression source = filter.Source;
						while( source.NodeType == NodeType.Filter )
						{
							source = (source as Filter).Source;
						}
						if( source.NodeType != NodeType.Property ) throw new Exception("Could not find source property for filter.");

						Property relProperty = (Property)source;
						if( !relProperty.IsRelational ) throw new Exception("Expected source property for Filter node to be relational.");

						RelationMap relation = relProperty.RelationMap;
						EntityMap sourceEntity = _maps[relProperty.OwnerClass];
						string sourceAlias = GetAlias(relProperty);

						string relationConstraint = ReplaceTableNameWithAlias(relation.Filter, sourceEntity.Table, sourceAlias);
						relationConstraint = ReplaceTableNameWithAlias(relationConstraint, entity.Table, entityAlias);
						
						switch( relation.Relationship )
						{
							case Relationship.Parent:
							{
								w.Write("SELECT *");
								WriteFromClause(w, entity.Table, entityAlias, null);
								if( entity.BaseEntity != null )
								{
									WriteSubEntityConstraint(w, entityAlias, entity.TypeField, entity.TypeValue, ref whereStarted);
								}
								WriteJoinCondition(w, sourceAlias, relation.Fields, entityAlias, GetFieldNames(entity.KeyFields), relationConstraint, true, ref whereStarted);
								WriteFilterConstraints(w, filter, whereStarted);
								break;
							}
							case Relationship.Child:
							{
								w.Write("SELECT *");
								WriteFromClause(w, entity.Table, entityAlias, null);
								if( entity.BaseEntity != null )
								{
									WriteSubEntityConstraint(w, entityAlias, entity.TypeField, entity.TypeValue, ref whereStarted);
								}
								WriteJoinCondition(w, sourceAlias, GetFieldNames(sourceEntity.KeyFields), entityAlias, relation.Fields, relationConstraint, true, ref whereStarted);
								WriteFilterConstraints(w, filter, whereStarted);
								break;
							}
							case Relationship.Many:
							{
								ManyMap junctionMap = (ManyMap)relation;
								string junctionAlias = GetNextAlias();

								relationConstraint = ReplaceTableNameWithAlias(relationConstraint, junctionMap.Table, junctionAlias);								

								// write the junction and child table, inner joined together in one select
								w.Write("SELECT *");
								WriteFromClause(w, junctionMap.Table, junctionAlias, null);
								w.Write(", ");
								WriteSqlTable(w, entity.Table, entityAlias);
								if( entity.BaseEntity != null )
								{
									WriteSubEntityConstraint(w, entityAlias, entity.TypeField, entity.TypeValue, ref whereStarted);
								}
								WriteJoinCondition(w, sourceAlias, GetFieldNames(sourceEntity.KeyFields), junctionAlias, junctionMap.Source, null, true, ref whereStarted);
								WriteJoinCondition(w, junctionAlias, junctionMap.Dest, entityAlias, GetFieldNames(entity.KeyFields), relationConstraint, true, ref whereStarted);
								WriteFilterConstraints(w, filter, whereStarted);

								break;
							}
							default:
							{
								throw new NotSupportedException("Relationship type '" + relation.Relationship + "' is not supported.");
							}
						}
					}
					else
					{
						throw new NotImplementedException("Filter with source type '" + filter.Source.NodeType + "' was not expected.");
					}
					return;
				}
				case NodeType.Function:
				{
					Function node = (Function)expr;

					bool isFormat;
					string keyword = GetSqlKeyword(node.Operator, out isFormat);
					if( isFormat )
					{
						WriteFormat(w, keyword, node.Params);
					}
					else
					{
						if( node.Operator != FunctionOperator.In )
						{
							throw new NotSupportedException("Function operator '" + node.Operator + "' was not expected.");
						}
						w.Write('(');
						WriteSqlQuery(w, node.Params[0]);
						w.Write(' ');
						w.Write(keyword);
						w.Write(" (");
						for( int i = 1; i < node.Params.Length; i++ )
						{
							if( i > 1 ) w.Write(", ");
							WriteSqlQuery(w, node.Params[i]);
						}
						w.Write("))");
					}
					return;
				}
				case NodeType.OrderBy:
				{
					OrderBy node = (OrderBy)expr;
					_orderByNode = node;

					Filter filter = (node.Source as Filter);
					if( filter == null )
					{
						throw new Exception("Expected source of OrderBy node to be Filter.");
					}

					WriteSqlQuery(w, filter);

					w.Write("\nORDER BY ");
					for( int i = 0; i < node.OrderByItems.Count; i++ )
					{
						OrderByItem item = node.OrderByItems[i];

						FieldMap field = item.FieldInfo;
						if( field == null )
						{
							throw new Exception("Field info does not exists for OrderByItem '" + item.Item + "'.");
						}

						string alias = (item.Join == null) ? filter.Alias : item.Join.Alias;

						if( i > 0 )	w.Write(", ");
						WriteSqlColumn(w, alias, field.Field);
						w.Write( (item.Ascending) ? " ASC" : " DESC");
					}
					return;
				}
				case NodeType.Empty:
				{
					return;
				}
				default:
				{
					throw new NotSupportedException("Expression type '" + expr.GetType() + "' is not currently supported.");
				}
			}
		}
コード例 #13
0
ファイル: Property.cs プロジェクト: Marceli/Roberta
 public Property(string name, Expression source)
 {
     this.Name = name;
     this.Source = source;
 }
コード例 #14
0
		private bool OleDbSetParameterOrderInFilter(Expression node, object[] args)
		{
			if( node.NodeType == NodeType.Filter )
			{
				// prevent enumerator from traversing child filters
				return false;
			}
			else if( node.NodeType == NodeType.Parameter )
			{
				int index = (node as Query.Parameter).Ordinal;
				int nextOrdinal = (int)args[0];
				_parameterTable[index].Ordinal = nextOrdinal;
				args[0] = nextOrdinal + 1;
			}
			return true;
		}
コード例 #15
0
		private bool OleDbSetParameterOrder(Expression node, object[] args)
		{
			if( node.NodeType == NodeType.Filter )
			{
				// the parameters in this filter are the next in sequence
				Filter filter = (Filter)node;
				Expression.EnumNodesCallBack callback = new Expression.EnumNodesCallBack(this.OleDbSetParameterOrderInFilter);
				Expression.EnumNodes(filter.Source, callback, null, args);
				Expression.EnumNodes(filter.Constraint, callback, null, args);
			}
			return true;
		}
コード例 #16
0
ファイル: TypeFilter.cs プロジェクト: cnporras/wilsonormapper
		public TypeFilter(Expression source, Type type, bool baseTypeOnly)
		{
			this.Source = source;
			this.Type = type;
			this.BaseTypeOnly = baseTypeOnly;
		}
コード例 #17
0
ファイル: TypeFilter.cs プロジェクト: cnporras/wilsonormapper
		public TypeFilter(Expression source, Type type) : this(source, type, false)
		{
		}
コード例 #18
0
ファイル: Binary.cs プロジェクト: tomtangrx/wilsonormapper
		public Binary(BinaryOperator op, Expression left, Expression right)
		{
			this.Operator = op;
			this.Left = left;
			this.Right = right;
		}
コード例 #19
0
ファイル: Binary.cs プロジェクト: Marceli/Roberta
        internal static Type GetResultType(Expression leftExpr, Expression rightExpr, BinaryOperator op)
        {
            if( IsOperatorBoolean(op) )
            {
                return typeof(bool);
            }

            if( op == BinaryOperator.Concatenation )
            {
                return typeof(string);
            }

            // if we make it here, we are deal with an Arithmetic operator

            //V2: the code below is a gross simplification or the actual logic that should be here truly deal with all the scenarios
            //    there is MUCH MUCH more to do here to fully implement this method.

            Type leftType = leftExpr.ValueType;
            Type rightType = rightExpr.ValueType;

            if( leftExpr.NodeType == NodeType.Parameter )
            {
                leftType = rightType; //V2: use inferredType?
            }
            else if( rightExpr.NodeType == NodeType.Parameter )
            {
                rightType = leftType; //V2: use inferredType?
            }

            // to simplify the logic convert char types to strings
            if( leftType == typeof(char) )
            {
                leftType = typeof(string);
            }
            if( rightType == typeof(char) )
            {
                rightType = typeof(string);
            }

            // a string combined with any other type equals a string
            if( leftType == typeof(string) || rightType == typeof(string) )
            {
                return typeof(string);
            }

            // a datetime combined with any other type equals a datetime
            if( leftType == typeof(DateTime) || rightType == typeof(DateTime) )
            {
                return typeof(DateTime);
            }

            // determine the precedence of the two types
            int leftIndex = GetPrecedenceIndex(leftType);
            int rightIndex = GetPrecedenceIndex(rightType);

            if( leftIndex == 0 || rightIndex == 0 )
            {
                //note: we should probably be throwing an error here
                return null;
            }

            // return the type with the higher precedence
            return (leftIndex >= rightIndex) ? leftType : rightType;
        }
コード例 #20
0
ファイル: Function.cs プロジェクト: Marceli/Roberta
 public override object Clone()
 {
     Expression[] args = new Expression[_args.Length];
     for( int i = 0; i < _args.Length; i++ )
     {
         args[i] = (Expression)_args[i].Clone();
     }
     return new Function(_op, args);
 }
コード例 #21
0
ファイル: Expression.cs プロジェクト: Marceli/Roberta
 public static void EnumNodes(Expression root, EnumNodesCallBack callback)
 {
     EnumNodes(root, callback, null, null);
 }
コード例 #22
0
ファイル: Function.cs プロジェクト: Marceli/Roberta
        private bool ValidateNoFilters(Expression node, object[] noargs)
        {
            if( node.NodeType == NodeType.Filter || node.NodeType == NodeType.Axis )
            {
                throw new OPathException("Relationship traversal found in parameter for " + GetDisplayName(_op) + " function.  Please move the traversal outside the function.");
            }

            return true;
        }
コード例 #23
0
ファイル: Expression.cs プロジェクト: Marceli/Roberta
        public static void Replace(Expression oldNode, Expression newNode)
        {
            if( oldNode == null ) throw new ArgumentNullException("oldNode");
            if( newNode == null ) throw new ArgumentNullException("newNode");

            Expression parent = oldNode.Owner;

            switch( parent.NodeType )
            {
                case NodeType.Axis:
                {
                    Axis axis = (Axis)parent;
                    if( axis.Source == oldNode )
                    {
                        axis.Source = newNode;
                    }
                    else if( axis.Constraint == oldNode )
                    {
                        axis.Constraint = newNode;
                    }
                    break;
                }
                case NodeType.Binary:
                {
                    Binary binary = (Binary)parent;
                    if( binary.Left == oldNode )
                    {
                        binary.Left = newNode;
                    }
                    else if( binary.Right == oldNode )
                    {
                        binary.Right = newNode;
                    }
                    break;
                }
                case NodeType.Filter:
                {
                    Filter filter = (Filter)parent;
                    if( filter.Source == oldNode )
                    {
                        filter.Source = newNode;
                    }
                    else if( filter.Constraint == oldNode )
                    {
                        filter.Constraint = newNode;
                    }
                    break;
                }
                case NodeType.Function:
                {
                    Function function = (Function)parent;
                    for( int i = 0; i < function.Params.Length; i++ )
                    {
                        if( function.Params[i] == oldNode )
                        {
                            function.Params[i] = newNode;
                        }
                    }
                    break;
                }
                case NodeType.Property:
                {
                    Property property = (Property)parent;
                    if( property.Source == oldNode )
                    {
                        property.Source = newNode;
                    }
                    break;
                }
                case NodeType.TypeFilter:
                {
                    TypeFilter filter = (TypeFilter)parent;
                    if( filter.Source == oldNode )
                    {
                        filter.Source = newNode;
                    }
                    break;
                }
                case NodeType.Unary:
                {
                    Unary unary = (Unary)parent;
                    if( unary.Operand == oldNode )
                    {
                        unary.Operand = newNode;
                    }
                    break;
                }
                default:
                {
                    throw new NotSupportedException("Node type '" + oldNode.Owner.NodeType + "' was not expected.");
                }
            }

            // remove old node's parent association
            oldNode.Parent = null;
        }
コード例 #24
0
ファイル: Axis.cs プロジェクト: cnporras/wilsonormapper
		public Axis(Expression source, Expression constraint) : base(source, constraint)
		{
			this.IsDot = true;
		}
コード例 #25
0
ファイル: OPath.cs プロジェクト: cnporras/wilsonormapper
		private bool IncreaseParentDepth(Expression node, object[] args)
		{
			if( node.NodeType == NodeType.Axis )
			{
				Axis axis = (Axis)node;
				IncreaseParentDepth((Property)axis.Source, args);
				return false;
			}
			else if( node.NodeType == NodeType.Property )
			{
				Property property = (Property)node;
				int parentCount = (int)args[0];
				for( int i = 0; i < parentCount; i++ )
				{
					property.Source = new Parent((Context)property.Source);
				}
				return false;
			}
			return true;
		}
コード例 #26
0
ファイル: Axis.cs プロジェクト: cnporras/wilsonormapper
		public Axis(Expression source, Expression constraint, bool isDot) : this(source, constraint)
		{
			this.IsDot = isDot;
		}
コード例 #27
0
ファイル: OPath.cs プロジェクト: cnporras/wilsonormapper
		private bool LinkPropertiesToMap(Expression node, object[] args)
		{
			if( node.NodeType == NodeType.Filter )
			{
				Filter filter = (Filter)node;
				Expression.EnumNodesCallBack callback = new Expression.EnumNodesCallBack(this.LinkPropertiesToMap);
				if( args.Length > 0 )
				{
					Expression.EnumNodes(filter.Source, callback, null, args);
				}

				// add the new filter to the font of the list
				object[] newArgs = new object[args.Length + 1];
				Array.Copy(args, 0, newArgs, 1, args.Length);
				newArgs[0] = filter;

				Expression.EnumNodes(filter.Constraint, callback, null, newArgs);
				return false;
			}
			else if( node.NodeType == NodeType.Property )
			{
				Property property = (Property)node;

				// determine the level of the filter to link
				int level = 0;
				if( property.Source.NodeType == NodeType.Parent )
				{
					level = (property.Source as Parent).Level;
					// replace the parent source with a new context for linking
					property.Source = new Context();
				}
				if( level >= args.Length )
				{
					throw new OPathException("Property '" + property.Name + "' could not be associated to an entity.");
				}

				// set the context link to the source of the filter
				Context context = (Context)property.Source;
				context.Link = (args[level] as Filter).Source;

				// set the property info
				SetPropertyInfo(property);
			}
			return true;
		}
コード例 #28
0
ファイル: Unary.cs プロジェクト: cnporras/wilsonormapper
		internal static Type GetResultType(Expression leftExpr, Expression rightExpr, BinaryOperator op)
		{
			throw new NotImplementedException();
		}
コード例 #29
0
ファイル: OPath.cs プロジェクト: cnporras/wilsonormapper
		private void Validate(Expression expr)
		{
			// validate every node in the tree
			Expression.EnumNodes(expr, new Expression.EnumNodesCallBack(this.ValidateNode));
		}
コード例 #30
0
ファイル: Unary.cs プロジェクト: cnporras/wilsonormapper
		public Unary(UnaryOperator op, Expression operand)
		{
			this.Operator = op;
			this.Operand = operand;
		}
コード例 #31
0
ファイル: OPath.cs プロジェクト: cnporras/wilsonormapper
		private void FixTree(Expression expr)
		{
			//Debug.WriteLine("\n\nBefore FixTree:\n" + expr.ToXmlString());

			//V2: This logic does not handle axis nodes in functions correctly.
			//V2: Need to crate a RecomposeFunction to move axis out from inside a function (or just don't let this happen - make them use []'s instead)
			//V2: Be sure to check that all properties in a function are of the same type.
			//	  Mixing relations in a function would be bad (e.g., LEN(BillAddress.Zip + ShipAddress.Zip)

			//V2: Expression.EnumNodes(expr, new Expression.EnumNodesCallBack(this.RecomposeFunction), null, (Function)null);
			//V2: Debug.WriteLine("\n\nAfter RecomposeFunction:\n" + expr.ToXmlString());

			// note: using a post callback to handle binary node chains correctly (found this out the hard way)
			Expression.EnumNodes(expr, null, new Expression.EnumNodesCallBack(this.RecomposeBinary), null);
			//Debug.WriteLine("\n\nAfter RecomposeBinary:\n" + expr.ToXmlString());

			Expression.EnumNodes(expr, new Expression.EnumNodesCallBack(this.ReplaceAxisCallback));
			//Debug.WriteLine("\n\nAfter ReplaceAxisCallback:\n" + expr.ToXmlString());

			Expression.EnumNodes(expr, new Expression.EnumNodesCallBack(this.LinkPropertiesToMap), null, new object[0]);
			//Debug.WriteLine("\n\nAfter LinkPropertiesToMap:\n" + expr.ToXmlString());

			Expression.EnumNodes(expr, new Expression.EnumNodesCallBack(this.ReplaceAddWithConcatenation), null, new object[0]);
			//Debug.WriteLine("\n\nAfter ReplaceAddWithConcatenation:\n" + expr.ToXmlString());

			//Debug.WriteLine("\n\nAfter FixTree:\n" + expr.ToXmlString());
		}
コード例 #32
0
ファイル: OPath.cs プロジェクト: Marceli/Roberta
 // note: internal longhorn name found on www.winfx247.com
 private bool ReplaceAddWithConcatenation(Expression node, object[] noargs)
 {
     if( node.NodeType == NodeType.Binary )
     {
         Binary binary = (Binary)node;
         if( binary.Operator == BinaryOperator.Addition && binary.Left.ValueType == typeof(string) && binary.Right.ValueType == typeof(string) )
         {
             binary.Operator = BinaryOperator.Concatenation;
         }
     }
     return true;
 }