⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 functionstack.cs

📁 NHibernate NET开发者所需的
💻 CS
字号:
using System;
using System.Collections.Generic;
using NHibernate.Dialect.Function;
using NHibernate.Engine;
using NHibernate.Type;

namespace NHibernate.Hql.Classic
{
	public class FunctionStack
	{
		private class FunctionHolder
		{
			private readonly PathExpressionParser pathExpressionParser = new PathExpressionParser();
			private readonly ISQLFunction sqlFunction;
			private readonly IFunctionGrammar functionGrammar;
			private IType firstValidColumnReturnType = null;

			public PathExpressionParser PathExpressionParser
			{
				get
				{
					FirstValidColumnType = pathExpressionParser.WhereColumnType;
					return pathExpressionParser;
				}
			}

			public ISQLFunction SqlFunction
			{
				get { return sqlFunction; }
			}

			public IFunctionGrammar FunctionGrammar
			{
				get { return functionGrammar; }
			}

			public FunctionHolder(ISQLFunction sqlFunction)
			{
				pathExpressionParser.UseThetaStyleJoin = true;
				this.sqlFunction = sqlFunction;
				functionGrammar = sqlFunction as IFunctionGrammar;
				if (functionGrammar == null)
					functionGrammar = new CommonGrammar();
			}

			/// <summary>
			/// Used to hold column type in nested functions.
			/// </summary>
			public IType FirstValidColumnType
			{
				get { return firstValidColumnReturnType; }
				set
				{
					if (firstValidColumnReturnType == null)
						firstValidColumnReturnType = value;
				}
			}
		}

		private readonly Stack<FunctionHolder> stack = new Stack<FunctionHolder>(5);
		private readonly IMapping mapping;
		
		public FunctionStack(IMapping mapping)
		{
			if (mapping == null)
			{
				throw new ArgumentNullException("mapping");
			}
			this.mapping = mapping;
		}

		public void Push(ISQLFunction sqlFunction)
		{
			if (sqlFunction == null)
			{
				throw new ArgumentNullException("sqlFunction");
			}
			stack.Push(new FunctionHolder(sqlFunction));
		}

		private FunctionHolder Peek()
		{
			return stack.Peek();
		}

		public void Pop()
		{
			IType firstReturnType;
			try
			{
				// Example in nested functions
				// abs(max(a.BodyWeight))
				// To know the ReturnType of "abs" we must know the ReturnType of "max" and the ReturnType of "max"
				// depend on the type of property "a.BodyWeight"
				FunctionHolder fh = Peek();
				firstReturnType = fh.SqlFunction.ReturnType(fh.FirstValidColumnType, mapping);
				stack.Pop();
			}
			catch (InvalidOperationException ex)
			{
				throw new QueryException("Parsing HQL: Pop on empty functions stack.", ex);
			}
			if (stack.Count > 0)
			{
				Peek().FirstValidColumnType = firstReturnType;
			}
		}

		public bool HasFunctions
		{
			get { return stack.Count > 0; }
		}

		public int NestedFunctionCount
		{
			get { return stack.Count; }
		}

		public PathExpressionParser PathExpressionParser
		{
			get { return Peek().PathExpressionParser; }
		}

		public ISQLFunction SqlFunction
		{
			get { return Peek().SqlFunction; }
		}

		public IFunctionGrammar FunctionGrammar
		{
			get { return Peek().FunctionGrammar; }
		}

		public IType GetReturnType()
		{
			FunctionHolder fh = Peek();
			IType result;
			try
			{
				result = fh.SqlFunction.ReturnType(fh.FirstValidColumnType, mapping);
			}
			catch(ArgumentNullException)
			{
				result = null;
			}
			if (result == null)
			{
				// magnify the exception
				throw new QueryException(string.Format("Can't extract the type of one parameter of a HQL function: expression->{{{0}}}; check aliases.",fh.PathExpressionParser.ProcessedPath));
			}
			return result;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -