示例#1
0
		public static ADOException Convert(ISQLExceptionConverter converter, Exception sqle, string message, SqlString sql,
		                                   object[] parameterValues, IDictionary<string, TypedValue> namedParameters)
		{
			sql = TryGetActualSqlQuery(sqle, sql);
			string extendMessage = ExtendMessage(message, sql.ToString(), parameterValues, namedParameters);
			ADOExceptionReporter.LogExceptions(sqle, extendMessage);
			return new ADOException(extendMessage, sqle, sql.ToString());
		}
		public void Replace()
		{
			SqlString sql =
				new SqlString(
					new object[] {"select ", "from table ", "where a = ", Parameter.Placeholder, " and c = ", Parameter.Placeholder});
			SqlString replacedSql = sql.Replace("table", "replacedTable");
			Assert.AreEqual(sql.ToString().Replace("table", "replacedTable"), replacedSql.ToString());

			replacedSql = sql.Replace("not found", "not in here");
			Assert.AreEqual(sql.ToString().Replace("not found", "not in here"), replacedSql.ToString(), "replace no found string");

			replacedSql = sql.Replace("le", "LE");
			Assert.AreEqual(sql.ToString().Replace("le", "LE"), replacedSql.ToString(), "multi-match replace");
		}
		/// <summary> 
		/// Converts the given SQLException into Exception hierarchy, as well as performing
		/// appropriate logging. 
		/// </summary>
		/// <param name="converter">The converter to use.</param>
		/// <param name="sqlException">The exception to convert.</param>
		/// <param name="message">An optional error message.</param>
		/// <param name="sql">The SQL executed.</param>
		/// <returns> The converted <see cref="ADOException"/>.</returns>
		public static Exception Convert(ISQLExceptionConverter converter, Exception sqlException, string message,
		                                   SqlString sql)
		{
			return Convert(converter,
			               new AdoExceptionContextInfo
			               	{SqlException = sqlException, Message = message, Sql = sql != null ? sql.ToString() : null});
		}
		protected void CompareSqlStrings(SqlString actualSqlString, string expectedString, int expectedNumOfParameters) 
		{
			Parameter[] actualParameters = new Parameter[expectedNumOfParameters];
			int numOfParameters = 0;

			GetParameters(actualSqlString, ref actualParameters, ref numOfParameters);
			Assert.AreEqual(expectedString, actualSqlString.ToString(), "SqlString.ToString()");
			Assert.AreEqual(expectedNumOfParameters, numOfParameters, "Num of Parameters");

		}
		public IDbCommand Generate(CommandType type, SqlString sqlString, SqlType[] parameterTypes)
		{
			IDbCommand cmd = factory.ConnectionProvider.Driver.GenerateCommand(type, sqlString, parameterTypes);
			LogOpenPreparedCommand();
			if (log.IsDebugEnabled)
			{
				log.Debug("Building an IDbCommand object for the SqlString: " + sqlString.ToString());
			}
			commandsToClose.Add(cmd);
			return cmd;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="sqlString"></param>
		/// <returns></returns>
		public IDbCommand Generate( SqlString sqlString )
		{
			// need to build the IDbCommand from the sqlString bec
			IDbCommand cmd = factory.ConnectionProvider.Driver.GenerateCommand( factory.Dialect, sqlString );
			LogOpenPreparedCommand();
			if( log.IsDebugEnabled )
			{
				log.Debug( "Building an IDbCommand object for the SqlString: " + sqlString.ToString() );
			}
			commandsToClose.Add( cmd );
			return cmd;
		}
		/// <summary>
		/// This method is a bit of a hack, and assumes
		/// that the column on the "right" side of the
		/// join appears on the "left" side of the
		/// operator, which is extremely weird if this
		/// was a normal join condition, but is natural
		/// for a filter.
		/// </summary>
		private void AddLeftOuterJoinCondition(SqlString on)
		{
			StringBuilder buf = new StringBuilder(on.ToString());
			for (int i = 0; i < buf.Length; i++)
			{
				char character = buf[i];
				bool isInsertPoint = Operators.Contains(character) ||
				                     (character == ' ' && buf.Length > i + 3 && "is ".Equals(buf.ToString(i + 1, 3)));
				if (isInsertPoint)
				{
					buf.Insert(i, "(+)");
					i += 3;
				}
			}
			AddCondition(SqlString.Parse(buf.ToString()));
		}
示例#8
0
		private void DetermineNumberOfPreceedingParametersForEachQuery(SqlString text)
		{
			int currentParameterIndex = 0;
			int currentQueryParameterCount = 0;
			int currentQueryIndex = 0;
			hasReturnParameter = false;
			foundReturnParameter = false;

			CallableParser.Detail callableDetail = CallableParser.Parse(text.ToString());

			if (callableDetail.IsCallable && callableDetail.HasReturn)
				hasReturnParameter = true;

			foreach (object part in text.Parts)
			{
				if (part.ToString().Equals(multipleQueriesSeparator))
				{
					queryIndexToNumberOfPreceedingParameters[currentQueryIndex] = currentParameterIndex - currentQueryParameterCount;
					currentQueryParameterCount = 0;
					currentQueryIndex++;
					continue;
				}

				Parameter parameter = part as Parameter;

				if (parameter != null)
				{
					if (hasReturnParameter && !foundReturnParameter)
					{
						foundReturnParameter = true;
					}
					else
					{
						parameterIndexToQueryIndex[currentParameterIndex] = currentQueryIndex;
					}
					currentQueryParameterCount++;
					currentParameterIndex++;
				}
			}
		}
		public void ProcessFilters(SqlString sql, ISessionImplementor session)
		{
			filteredParameterValues = new List<object>();
			filteredParameterTypes = new List<IType>();
			filteredParameterLocations = new List<int>();

			if (session.EnabledFilters.Count == 0 || sql.ToString().IndexOf(ParserHelper.HqlVariablePrefix) < 0)
			{
				processedSQL = sql.Copy();
				return;
			}

			Dialect.Dialect dialect = session.Factory.Dialect;
			string symbols = ParserHelper.HqlSeparators + dialect.OpenQuote + dialect.CloseQuote;

			var result = new SqlStringBuilder();

			int originalParameterIndex = 0; // keep track of the positional parameter
			int newParameterIndex = 0;
			_adjustedParameterLocations = new Dictionary<int, int>();

			foreach (var part in sql.Parts)
			{
				if (part is Parameter)
				{
					result.AddParameter();

					// (?) can be a position parameter or a named parameter (already substituted by (?),
					// but only the positional parameters are available at this point. Adding them in the
					// order of appearance is best that can be done at this point of time, but if they
					// are mixed with named parameters, the order is still wrong, because values and
					// types for the named parameters are added later to the end of the list.
					// see test fixture NH-1098

					_adjustedParameterLocations[originalParameterIndex] = newParameterIndex;
					originalParameterIndex++;
					newParameterIndex++;
					continue;
				}

				var tokenizer = new StringTokenizer((string) part, symbols, true);

				foreach (var token in tokenizer)
				{
					if (token.StartsWith(ParserHelper.HqlVariablePrefix))
					{
						string filterParameterName = token.Substring(1);
						object value = session.GetFilterParameterValue(filterParameterName);
						IType type = session.GetFilterParameterType(filterParameterName);

						// If the value is not a value of the type but a collection of values...
						if (value != null && !type.ReturnedClass.IsAssignableFrom(value.GetType()) && // Added to fix NH-882
						    typeof (ICollection).IsAssignableFrom(value.GetType()))
						{
							var coll = (ICollection) value;
							int i = 0;
							foreach (var elementValue in coll)
							{
								i++;
								int span = type.GetColumnSpan(session.Factory);
								if (span > 0)
								{
									result.AddParameter();
									filteredParameterTypes.Add(type);
									filteredParameterValues.Add(elementValue);
									filteredParameterLocations.Add(newParameterIndex);
									newParameterIndex++;
									if (i < coll.Count)
									{
										result.Add(", ");
									}
								}
							}
						}
						else
						{
							int span = type.GetColumnSpan(session.Factory);
							if (span > 0)
							{
								result.AddParameter();
								filteredParameterTypes.Add(type);
								filteredParameterValues.Add(value);
								filteredParameterLocations.Add(newParameterIndex);
								newParameterIndex++;
							}
						}
					}
					else
					{
						result.Add(token);
					}
				}
			}

			processedSQL = result.ToSqlString();
		}
		public void TrimBeginStringEndParam()
		{
			Parameter p1 = Parameter.Placeholder;

			SqlString sql = new SqlString(new object[] { "   extra space   ", p1 });
			sql = sql.Trim();

			Assert.AreEqual("extra space   ?", sql.ToString());
		}
		public void TrimAllParam()
		{
			Parameter p1 = Parameter.Placeholder;
			Parameter p2 = Parameter.Placeholder;

			SqlString sql = new SqlString(new object[] { p1, p2 });
			sql = sql.Trim();

			Assert.AreEqual("??", sql.ToString());
		}
		public void TrimAllString()
		{
			SqlString sql = new SqlString(new string[] { "   extra space", " in the middle", " at the end     " });
			sql = sql.Trim();

			Assert.AreEqual("extra space in the middle at the end", sql.ToString());
		}
		public void TrimBeginParamEndString()
		{
			Parameter p1 = Parameter.Placeholder;

			SqlString sql = new SqlString(new object[] { p1, "   extra space   " });
			sql = sql.Trim();

			Assert.AreEqual("?   extra space", sql.ToString());
		}
示例#14
0
		public static void ProcessDynamicFilterParameters(
				SqlString sqlFragment,
				IParameterContainer container,
				HqlSqlWalker walker) 
		{
			if ( walker.EnabledFilters.Count == 0
					&& ( ! HasDynamicFilterParam( sqlFragment ) )
					&& ( ! ( HasCollectionFilterParam( sqlFragment ) ) ) ) 
			{
				return;
			}

			Dialect.Dialect dialect = walker.SessionFactoryHelper.Factory.Dialect;

			string symbols = new StringBuilder().Append( ParserHelper.HqlSeparators )
					.Append( dialect.OpenQuote)
					.Append( dialect.CloseQuote)
					.ToString();

			StringTokenizer tokens = new StringTokenizer( sqlFragment.ToString(), symbols, true );
			StringBuilder result = new StringBuilder();

			foreach (string token in tokens)
			{
				if ( token.StartsWith( ParserHelper.HqlVariablePrefix ) ) 
				{
					string filterParameterName = token.Substring( 1 );
					string[] parts = StringHelper.ParseFilterParameterName( filterParameterName );
					FilterImpl filter = ( FilterImpl ) walker.EnabledFilters[parts[0]];
					Object value = filter.GetParameter( parts[1] );
					IType type = filter.FilterDefinition.GetParameterType( parts[1] );
					String typeBindFragment = StringHelper.Join(
							",",
							ArrayHelper.FillArray( "?", type.GetColumnSpan( walker.SessionFactoryHelper.Factory ) )
					);
					string bindFragment = ( value != null && value is ICollection)
							? StringHelper.Join( ",", ArrayHelper.FillArray( typeBindFragment, ( ( ICollection ) value ).Count ) )
							: typeBindFragment;
					//result.Append( bindFragment );
					result.Append(token);
					container.AddEmbeddedParameter( new DynamicFilterParameterSpecification( parts[0], parts[1], type ) );
				}
				else 
				{
					result.Append( token );
				}
			}

			container.Text = result.ToString();
		}
示例#15
0
		/// <summary>
		/// Sets the text that should appear after the FROM
		/// </summary>
		/// <param name="fromClause">The fromClause in a SqlString</param>
		/// <returns>The SqlSelectBuilder</returns>
		public SqlSelectBuilder SetFromClause(SqlString fromClause)
		{
			// it is safe to do this because a fromClause will have no
			// parameters
			return SetFromClause(fromClause.ToString());
		}
示例#16
0
		protected SqlString ExpandDynamicFilterParameters(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, ISessionImplementor session)
		{
			var enabledFilters = session.EnabledFilters;
			if (enabledFilters.Count == 0 || sqlString.ToString().IndexOf(ParserHelper.HqlVariablePrefix) < 0)
			{
				return sqlString;
			}

			Dialect.Dialect dialect = session.Factory.Dialect;
			string symbols = ParserHelper.HqlSeparators + dialect.OpenQuote + dialect.CloseQuote;

			var originSql = sqlString.Compact();
			var result = new SqlStringBuilder();
			foreach (var sqlPart in originSql.Parts)
			{
				var parameter = sqlPart as Parameter;
				if (parameter != null)
				{
					result.Add(parameter);
					continue;
				}

				var sqlFragment = sqlPart.ToString();
				var tokens = new StringTokenizer(sqlFragment, symbols, true);

				foreach (string token in tokens)
				{
					if (token.StartsWith(ParserHelper.HqlVariablePrefix))
					{
						string filterParameterName = token.Substring(1);
						string[] parts = StringHelper.ParseFilterParameterName(filterParameterName);
						string filterName = parts[0];
						string parameterName = parts[1];
						var filter = (FilterImpl)enabledFilters[filterName];

						object value = filter.GetParameter(parameterName);
						IType type = filter.FilterDefinition.GetParameterType(parameterName);
						int parameterColumnSpan = type.GetColumnSpan(session.Factory);
						var collectionValue = value as ICollection;
						int? collectionSpan = null;

						// Add query chunk
						string typeBindFragment = string.Join(", ", Enumerable.Repeat("?", parameterColumnSpan).ToArray());
						string bindFragment;
						if (collectionValue != null && !type.ReturnedClass.IsArray)
						{
							collectionSpan = collectionValue.Count;
							bindFragment = string.Join(", ", Enumerable.Repeat(typeBindFragment, collectionValue.Count).ToArray());
						}
						else
						{
							bindFragment = typeBindFragment;
						}

						// dynamic-filter parameter tracking
						var filterParameterFragment = SqlString.Parse(bindFragment);
						var dynamicFilterParameterSpecification = new DynamicFilterParameterSpecification(filterName, parameterName, type, collectionSpan);
						var parameters = filterParameterFragment.GetParameters().ToArray();
						var sqlParameterPos = 0;
						var paramTrackers = dynamicFilterParameterSpecification.GetIdsForBackTrack(session.Factory);
						foreach (var paramTracker in paramTrackers)
						{
							parameters[sqlParameterPos++].BackTrack = paramTracker;
						}

						parameterSpecs.Add(dynamicFilterParameterSpecification);
						result.Add(filterParameterFragment);
					}
					else
					{
						result.Add(token);
					}
				}
			}
			return result.ToSqlString().Compact();
		}
示例#17
0
		void ISqlStringVisitor.String(SqlString sqlString)
		{
			result.Append(sqlString.ToString());
		}
示例#18
0
        /// <summary>Use GenerateCommand to fix Jet issues or temporary 
        ///          bugs of NHibernate that affect JetDriver
        /// </summary>
        /// <param name="type"></param>
        /// <param name="sqlString"></param>
        /// <param name="parameterTypes"></param>
        /// <returns></returns>
        public override IDbCommand GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes)
        {
            var parametersOriginal = new List<Parameter>();

            var sql = sqlString.ToString();

            foreach (var part in sqlString)
            {
                if (part is Parameter)
                {
                    parametersOriginal.Add((Parameter)part);
                }
            }

            Regex regexReplaceParam = new Regex(
              "\\?",
            RegexOptions.IgnoreCase
            | RegexOptions.Singleline
            | RegexOptions.CultureInvariant
            );

            int i = 0;
            foreach (var param in parametersOriginal)
            {
                if (param.ParameterPosition == null)
                {
                    param.ParameterPosition = i;
                }
                sql = regexReplaceParam.Replace(sql, String.Format("@p{0}", param.ParameterPosition), 1);
                i++;
            }

            var sqlFixed = sql;

            if (_sqlFixes.Length > 0)
            {

                foreach (var sqlStringFix in _sqlFixes)
                {
                    sqlFixed = sqlStringFix.FixSql(sqlFixed);
                }

            }

            SqlString final = RestoreParameters(parametersOriginal, sqlFixed);

            var fromParts = ExtractFromParts(final);

            foreach (var ansiJoinWithEndMarker in fromParts)
            {
                var ansiFrom = ansiJoinWithEndMarker.Replace(JetJoinFragment.EndJoin, "");

                var sb = new SqlStringBuilder();

                //convert ansi from to access from
                sb.Add("SELECT *" + ansiFrom);
                var sqlJetFrom = FinalizeJoins(sb.ToSqlString());
                sqlJetFrom = sqlJetFrom.Replace("SELECT *", "");
                string accessFrom = sqlJetFrom.ToString();

                var start = final.IndexOfCaseInsensitive(ansiJoinWithEndMarker);
                sb = new SqlStringBuilder();
                if (start > 0)
                {
                    sb.Add(final.Substring(0, start));
                    sb.Add(accessFrom);
                    sb.Add(final.Substring(start + ansiJoinWithEndMarker.Length));
                    final = sb.ToSqlString();
                }
            }

            return base.GenerateCommand(type, final, parameterTypes);
        }
		/// <summary>
		/// This compares the text output of the SqlString to what was expected.  It does
		/// not take into account the parameters.
		/// </summary>
		protected void CompareSqlStrings(SqlString actualSqlString, string expectedString)
		{
			Assert.AreEqual(expectedString, actualSqlString.ToString(), "SqlString.ToString()");
		}
示例#20
0
        private void RestoreMissingParameters(SqlString originalSQL, ref SqlString transformedSQL)
        {
            if (originalSQL.Equals(transformedSQL))
            {
                return;
            }

            var parametersOriginal = new ArrayList();
            var parametersTransformed = new ArrayList();

            foreach (var part in originalSQL)
            {
                if (part is Parameter)
                {
                    parametersOriginal.Add(part);
                }
            }

            foreach (var part in transformedSQL)
            {
                if (part is Parameter)
                {
                    parametersTransformed.Add(part);
                }
            }

            //same number of parameters , return
            if (parametersOriginal.Count == parametersTransformed.Count)
            {
                return;
            }

            //fix missing parameters spliting around '?'
            var sqlText = transformedSQL.ToString();
            Regex regex = new Regex("@x\\d+",
                                    RegexOptions.IgnoreCase
                                    | RegexOptions.CultureInvariant
                                    );

            var parametersParts = regex.Split(sqlText);

            //parametersParts = sqlText.Split('?');

            if ((parametersParts.Length - 1) != parametersOriginal.Count)
            {
                //can't restore
                throw new QueryException("FinalizeJoins JetDriver removed SQL parameteres and can not be restored");
            }

            var sqlBuilder = new SqlStringBuilder();

            for (int i = 0; i < parametersParts.Length; i++)
            {
                if (i > 0)
                {
                    sqlBuilder.AddObject(parametersOriginal[i - 1]);
                }

                sqlBuilder.Add(parametersParts[i]);
            }

            transformedSQL = sqlBuilder.ToSqlString();
        }
示例#21
0
        private List<string> ExtractFromParts(SqlString sqlString)
        {
            var parts = new List<string>();
            var sql = sqlString.ToString();
            var joinTags = ParseJoinNodes(sql);

            var i = 0;
            while (i < joinTags.Count)
            {
                var fromStart = -1;
                var fromEnd = -1;

                while ((i < joinTags.Count) && (joinTags[i].Name == FromClause))
                {
                    fromStart = joinTags[i].Position;
                    i++;
                }

                while ((i < joinTags.Count) && (joinTags[i].Name == JetJoinFragment.EndJoin))
                {
                    fromEnd = joinTags[i].Position;
                    i++;
                }

                if ((fromStart >= 0) && (fromEnd > fromStart))
                {
                    parts.Add(sql.Substring(fromStart, fromEnd + JetJoinFragment.EndJoin.Length - fromStart));
                }

            }

            return parts;
        }
 public override SqlString OnPrepareStatement(SqlString sql)
 {
     Trace.WriteLine(sql.ToString());
     return base.OnPrepareStatement(sql);
 }
		public void AddWhereFragment(
				JoinFragment joinFragment,
				SqlString whereFragment,
				QueryNode query,
				FromElement fromElement,
				HqlSqlWalker hqlSqlWalker)
		{
			if (whereFragment == null)
			{
				return;
			}

			if (!fromElement.UseWhereFragment && !joinFragment.HasThetaJoins)
			{
				return;
			}

			whereFragment = whereFragment.Trim();
			if (StringHelper.IsEmpty(whereFragment.ToString()))
			{
				return;
			}

			// Forcefully remove leading ands from where fragments; the grammar will
			// handle adding them
			if (whereFragment.StartsWithCaseInsensitive("and"))
			{
				whereFragment = whereFragment.Substring(4);
			}

			log.Debug("Using unprocessed WHERE-fragment [" + whereFragment +"]");

			SqlFragment fragment = (SqlFragment) Create(HqlSqlWalker.SQL_TOKEN, whereFragment.ToString());

			fragment.SetJoinFragment(joinFragment);
			fragment.FromElement = fromElement;

			if (fromElement.IndexCollectionSelectorParamSpec != null)
			{
				fragment.AddEmbeddedParameter(fromElement.IndexCollectionSelectorParamSpec);
				fromElement.IndexCollectionSelectorParamSpec = null;
			}

			if (hqlSqlWalker.IsFilter())
			{
				//if (whereFragment.IndexOfCaseInsensitive("?") >= 0)
                if (whereFragment.ToString().IndexOf("?") >= 0)
                {
					IType collectionFilterKeyType = hqlSqlWalker.SessionFactoryHelper
							.RequireQueryableCollection(hqlSqlWalker.CollectionFilterRole)
							.KeyType;
					CollectionFilterKeyParameterSpecification paramSpec = new CollectionFilterKeyParameterSpecification(
							hqlSqlWalker.CollectionFilterRole,
							collectionFilterKeyType,
							0
					);
					fragment.AddEmbeddedParameter(paramSpec);
				}
			}

			JoinProcessor.ProcessDynamicFilterParameters(
					whereFragment,
					fragment,
					hqlSqlWalker
			);

			log.Debug("Using processed WHERE-fragment [" + fragment.Text + "]");

			// Filter conditions need to be inserted before the HQL where condition and the
			// theta join node.  This is because org.hibernate.loader.Loader binds the filter parameters first,
			// then it binds all the HQL query parameters, see org.hibernate.loader.Loader.processFilterParameters().
			if (fragment.FromElement.IsFilter || fragment.HasFilterCondition)
			{
				if (_filters == null)
				{
					// Find or create the WHERE clause
					IASTNode where = (IASTNode) query.WhereClause;
					// Create a new FILTERS node as a parent of all filters
					_filters = Create(HqlSqlWalker.FILTERS, "{filter conditions}");
					// Put the FILTERS node before the HQL condition and theta joins
					where.InsertChild(0, _filters);
				}

				// add the current fragment to the FILTERS node
				_filters.AddChild(fragment);
			}
			else
			{
				if (_thetaJoins == null)
				{
					// Find or create the WHERE clause
					IASTNode where = (IASTNode) query.WhereClause;

					// Create a new THETA_JOINS node as a parent of all filters
					_thetaJoins = Create(HqlSqlWalker.THETA_JOINS, "{theta joins}");

					// Put the THETA_JOINS node before the HQL condition, after the filters.
					if (_filters == null)
					{
						where.InsertChild(0, _thetaJoins);
					}
					else
					{
                        _filters.AddSibling(_thetaJoins);
					}
				}

				// add the current fragment to the THETA_JOINS node
				_thetaJoins.AddChild(fragment);
			}
		}
示例#24
0
		public static void ProcessDynamicFilterParameters(
				SqlString sqlFragment,
				IParameterContainer container,
				HqlSqlWalker walker) 
		{
			if ( walker.EnabledFilters.Count == 0
					&& ( ! HasDynamicFilterParam( sqlFragment ) )
					&& ( ! ( HasCollectionFilterParam( sqlFragment ) ) ) ) 
			{
				return;
			}

			container.Text = sqlFragment.ToString(); // dynamic-filters are processed altogether by Loader
		}
示例#25
0
		private static int GetFromIndex(SqlString querySqlString)
		{
			string subselect = querySqlString.GetSubselectString().ToString();
			int fromIndex = querySqlString.IndexOfCaseInsensitive(subselect);
			if (fromIndex == -1)
			{
				fromIndex = querySqlString.ToString().ToLowerInvariant().IndexOf(subselect.ToLowerInvariant());
			}
			return fromIndex;
		}
        SqlString IInterceptor.OnPrepareStatement(SqlString sql)
        {
            LastExecutedQuery = sql.ToString();

            return sql;
        }        
		protected void CompareSqlStrings(SqlString actualSqlString, string expectedString, int expectedNumOfParameters)
		{
			Assert.AreEqual(expectedString, actualSqlString.ToString(), "SqlString.ToString()");
			Assert.AreEqual(expectedNumOfParameters, actualSqlString.GetParameterCount(), "Num of Parameters");
		}
		public override SqlString ApplyLocksToSql(SqlString sql, IDictionary<string, LockMode> aliasedLockModes, IDictionary<string, string[]> keyColumnNames)
		{
			// TODO:  merge additional lockoptions support in Dialect.applyLocksToSql

			var buffer = new StringBuilder(sql.ToString());
			int correction = 0;
			
			foreach (KeyValuePair<string, LockMode> entry in aliasedLockModes)
			{
				LockMode mode = entry.Value;
				
				if (mode.GreaterThan(LockMode.Read))
				{
					string alias = entry.Key;
					int start = -1;
					int end = -1;
					
					if (sql.EndsWith(" " + alias))
					{
						start = (sql.Length - alias.Length) + correction;
						end = start + alias.Length;
					}
					else
					{
						int position = sql.IndexOfCaseInsensitive(" " + alias + " ");
						
						if (position <= -1)
							position = sql.IndexOfCaseInsensitive(" " + alias + ",");
						
						if (position > -1)
						{
							start = position + correction + 1;
							end = start + alias.Length;
						}
					}
					
					if (start > -1)
					{
						string lockHint = AppendLockHint(mode, alias);
						buffer.Remove(start, end - start + 1);
						buffer.Insert(start, lockHint);
						correction += (lockHint.Length - alias.Length);
					}
				}
			}
			return new SqlString(buffer.ToString());
		}
		protected void InitProjection(SqlString projectionString, SqlString whereString, SqlString orderByString, SqlString groupByString, SqlString havingString, IDictionary<string, IFilter> enabledFilters, LockMode lockMode)
		{
			WalkEntityTree(persister, Alias);
			Persisters = new ILoadable[0];
			InitStatementString(projectionString, whereString, orderByString, groupByString.ToString(), havingString, lockMode);
		}
 public override NHibernate.SqlCommand.SqlString OnPrepareStatement(NHibernate.SqlCommand.SqlString sql)
 {
     Trace.WriteLine(sql.ToString());
     return(sql);
 }
		private void ProcessGeneratedProperties(object id, object entity, object[] state,
				ISessionImplementor session, SqlString selectionSQL, ValueInclusion[] includeds)
		{
			session.Batcher.ExecuteBatch(); //force immediate execution of the insert

			using (new SessionIdLoggingContext(session.SessionId)) 
			try
			{
				IDbCommand cmd =
					session.Batcher.PrepareQueryCommand(CommandType.Text, selectionSQL, IdentifierType.SqlTypes(Factory));
				IDataReader rs = null;
				try
				{
					IdentifierType.NullSafeSet(cmd, id, 0, session);
					rs = session.Batcher.ExecuteReader(cmd);
					if (!rs.Read())
					{
						throw new HibernateException("Unable to locate row for retrieval of generated properties: "
																				 + MessageHelper.InfoString(this, id, Factory));
					}
					for (int i = 0; i < PropertySpan; i++)
					{
						if (includeds[i] != ValueInclusion.None)
						{
							object hydratedState = PropertyTypes[i].Hydrate(rs, GetPropertyAliases(string.Empty, i), session, entity);
							state[i] = PropertyTypes[i].ResolveIdentifier(hydratedState, session, entity);
							SetPropertyValue(entity, i, state[i], session.EntityMode);
						}
					}
				}
				finally
				{
					session.Batcher.CloseCommand(cmd, rs);
				}
			}
			catch (DbException sqle)
			{
				var exceptionContext = new AdoExceptionContextInfo
				                       	{
				                       		SqlException = sqle,
				                       		Message = "unable to select generated column values",
				                       		Sql = selectionSQL.ToString(),
				                       		EntityName = EntityName,
				                       		EntityId = id
				                       	};
				throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, exceptionContext);
			}
		}
 /// <summary>
 /// Sets the text that should appear after the FROM
 /// </summary>
 /// <param name="fromClause">The fromClause in a SqlString</param>
 /// <returns>The SqlSelectBuilder</returns>
 public SqlSelectBuilder SetFromClause(SqlString fromClause)
 {
     // it is safe to do this because a fromClause will have no
     // parameters
     return(SetFromClause(fromClause.ToString()));
 }