public SubselectOneToManyLoader(IQueryableCollection persister, SqlString subquery, ICollection<EntityKey> entityKeys,
		                                QueryParameters queryParameters,
		                                ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters)
			: base(persister, BatchSizeForSubselectFetching, factory, enabledFilters)
		{
			keys = new object[entityKeys.Count];
			int i = 0;
			foreach (EntityKey entityKey in entityKeys)
			{
				keys[i++] = entityKey.Identifier;
			}

			// NH Different behavior: to deal with positionslParameter+NamedParameter+ParameterOfFilters
			namedParameters = new Dictionary<string, TypedValue>(queryParameters.NamedParameters);
			parametersSpecifications = queryParameters.ProcessedSqlParameters.ToList();
			var processedRowSelection = queryParameters.ProcessedRowSelection;
			SqlString finalSubquery = subquery;
			if (queryParameters.ProcessedRowSelection != null && !SubselectClauseExtractor.HasOrderBy(queryParameters.ProcessedSql))
			{
				// when the original query has an "ORDER BY" we can't re-apply the pagination.
				// This is a simplification, we should actually check which is the "ORDER BY" clause because when the "ORDER BY" is just for the PK we can re-apply "ORDER BY" and pagination.
				finalSubquery = GetSubSelectWithLimits(subquery, parametersSpecifications, processedRowSelection, namedParameters);
			}
			InitializeFromWalker(persister, finalSubquery, BatchSizeForSubselectFetching, enabledFilters, factory);

			types = queryParameters.PositionalParameterTypes;
			values = queryParameters.PositionalParameterValues;
		}
예제 #2
0
		public SqlCommandImpl(SqlString query, ICollection<IParameterSpecification> specifications, QueryParameters queryParameters, ISessionFactoryImplementor factory)
		{
			this.query = query;
			this.specifications = specifications;
			this.queryParameters = queryParameters;
			this.factory = factory;
		}
		public void ValidateFailureDifferentLengths()
		{
			QueryParameters qp = new QueryParameters(
				new IType[] { NHibernateUtil.String },
				new object[] { });

			qp.ValidateParameters();
		}
		public void ValidateOk()
		{
			QueryParameters qp = new QueryParameters(
				new IType[] {NHibernateUtil.String},
				new object[] {"string"});

			qp.ValidateParameters();
		}
		public void ValidateFailureDifferentLengths()
		{
			QueryParameters qp = new QueryParameters(
				new IType[] {NHibernateUtil.String},
				new object[] {});

			Assert.Throws<QueryException>(() => qp.ValidateParameters());
		}
		public static void ResetEffectiveExpectedType(this IEnumerable<IParameterSpecification> parameterSpecs, QueryParameters queryParameters)
		{
			// TODO: remove this method when we can infer the type during the parse
			foreach (var parameterSpecification in parameterSpecs.OfType<IExplicitParameterSpecification>())
			{
				parameterSpecification.SetEffectiveType(queryParameters);
			}
		}
		public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
		{
			ISessionFactoryImplementor factory = criteriaQuery.Factory;

			var innerQuery = new CriteriaQueryTranslator(
				factory,
				criteriaImpl, //implicit polymorphism not supported (would need a union)
				criteriaImpl.EntityOrClassName,
				criteriaQuery.GenerateSQLAlias(),
				criteriaQuery);

			types = innerQuery.HasProjection ? innerQuery.ProjectedTypes : null;

			if (innerQuery.HasProjection == false)
			{
				throw new QueryException("Cannot use subqueries on a criteria without a projection.");
			}

			IOuterJoinLoadable persister = (IOuterJoinLoadable) factory.GetEntityPersister(criteriaImpl.EntityOrClassName);

			//patch to generate joins on subqueries
			//stolen from CriteriaLoader
			CriteriaJoinWalker walker =
				new CriteriaJoinWalker(persister, innerQuery, factory, criteriaImpl, criteriaImpl.EntityOrClassName, enabledFilters);

			parameters = innerQuery.GetQueryParameters(); // parameters can be inferred only after initialize the walker

			SqlString sql = walker.SqlString;

			if (criteriaImpl.FirstResult != 0 || criteriaImpl.MaxResults != RowSelection.NoValue)
			{
				int? offset = Loader.Loader.GetOffsetUsingDialect(parameters.RowSelection, factory.Dialect);
				int? limit = Loader.Loader.GetLimitUsingDialect(parameters.RowSelection, factory.Dialect);
				Parameter offsetParameter = offset.HasValue ? innerQuery.CreateSkipParameter(offset.Value) : null;
				Parameter limitParameter = limit.HasValue ? innerQuery.CreateTakeParameter(limit.Value) : null;
				sql = factory.Dialect.GetLimitString(sql, offset, limit, offsetParameter, limitParameter);
			}

			SqlStringBuilder buf = new SqlStringBuilder().Add(ToLeftSqlString(criteria, criteriaQuery));
			if (op != null)
			{
				buf.Add(" ").Add(op).Add(" ");
			}

			if (quantifier != null && prefixOp)
			{
				buf.Add(quantifier).Add(" ");
			}

			buf.Add("(").Add(sql).Add(")");

			if (quantifier != null && prefixOp == false)
			{
				buf.Add(" ").Add(quantifier);
			}

			return buf.ToSqlString();
		}
		public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session)
		{
			IType type = keyType;
			object value = queryParameters.PositionalParameterValues[queryParameterPosition];

			string backTrackId = GetIdsForBackTrack(session.Factory).First(); // just the first because IType suppose the oders in certain sequence
			int position = sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId).Single(); // an HQL positional parameter can't appear more than once
			type.NullSafeSet(command, value, position + singleSqlParametersOffset, session);
		}
예제 #9
0
		protected virtual int BindLimitParametersLastIfNeccesary(IDbCommand command, QueryParameters parameter, int colIndex)
		{
			RowSelection selection = parameter.RowSelection;
			if (Loader.Loader.UseLimit(selection, dialect) && !dialect.BindLimitParametersFirst)
			{
				return Loader.Loader.BindLimitParameters(command, colIndex, selection, session);
			}
			return 0;
		}
		public override void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session)
		{
			TypedValue typedValue = queryParameters.NamedParameters[name];
			string backTrackId = GetIdsForBackTrack(session.Factory).First(); // just the first because IType suppose the oders in certain sequence
			foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId))
			{
				ExpectedType.NullSafeSet(command, GetPagingValue(typedValue.Value, session.Factory.Dialect, queryParameters), position + singleSqlParametersOffset, session);
			}
		}
		public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session)
		{
			TypedValue typedValue = queryParameters.NamedParameters[name];
			string backTrackId = GetIdsForBackTrack(session.Factory).First();
			foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId))
			{
				ExpectedType.NullSafeSet(command, typedValue.Value, position + singleSqlParametersOffset, session);
			}
		}
예제 #12
0
		public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
		{
			InitializeInnerQueryAndParameters(criteriaQuery);

			if (innerQuery.HasProjection == false)
			{
				throw new QueryException("Cannot use subqueries on a criteria without a projection.");
			}

			ISessionFactoryImplementor factory = criteriaQuery.Factory;

			IOuterJoinLoadable persister = (IOuterJoinLoadable)factory.GetEntityPersister(criteriaImpl.EntityOrClassName);

			//patch to generate joins on subqueries
			//stolen from CriteriaLoader
			CriteriaJoinWalker walker =
				new CriteriaJoinWalker(persister, innerQuery, factory, criteriaImpl, criteriaImpl.EntityOrClassName, enabledFilters);

			parameters = innerQuery.GetQueryParameters(); // parameters can be inferred only after initialize the walker

			SqlString sql = walker.SqlString;

			if (criteriaImpl.FirstResult != 0 || criteriaImpl.MaxResults != RowSelection.NoValue)
			{
				int? offset = Loader.Loader.GetOffsetUsingDialect(parameters.RowSelection, factory.Dialect);
				int? limit = Loader.Loader.GetLimitUsingDialect(parameters.RowSelection, factory.Dialect);
				Parameter offsetParameter = offset.HasValue ? innerQuery.CreateSkipParameter(offset.Value) : null;
				Parameter limitParameter = limit.HasValue ? innerQuery.CreateTakeParameter(limit.Value) : null;
				sql = factory.Dialect.GetLimitString(sql, offset, limit, offsetParameter, limitParameter);
			}

			// during CriteriaImpl.Clone we are doing a shallow copy of each criterion.
			// this is not a problem for common criterion but not for SubqueryExpression because here we are holding the state of inner CriteriaTraslator (ICriteriaQuery).
			// After execution (ToSqlString) we have to clean the internal state because the next execution may be performed in a different tree reusing the same istance of SubqueryExpression.
			innerQuery = null;

			SqlStringBuilder buf = new SqlStringBuilder().Add(ToLeftSqlString(criteria, criteriaQuery));
			if (op != null)
			{
				buf.Add(" ").Add(op).Add(" ");
			}

			if (quantifier != null && prefixOp)
			{
				buf.Add(quantifier).Add(" ");
			}
			
			buf.Add("(").Add(sql).Add(")");

			if (quantifier != null && prefixOp == false)
			{
				buf.Add(" ").Add(quantifier);
			}

			return buf.ToSqlString();
		}
		public int Bind(
			IDbCommand statement,
			QueryParameters qp,
			ISessionImplementor session,
			int position)
		{
			object value = qp.PositionalParameterValues[_queryParameterPosition];
			_keyType.NullSafeSet(statement, value, position, session);
			return _keyType.GetColumnSpan(session.Factory);
		}
		public int Bind(IDbCommand statement, QueryParameters qp, ISessionImplementor session, int position)
		{
			int bindCount = 0;

			foreach (IParameterSpecification spec in _paramSpecs)
			{
				bindCount += spec.Bind(statement, qp, session, position + bindCount);
			}
			return bindCount;
		}
예제 #15
0
		public SubselectFetch(string alias, ILoadable loadable, QueryParameters queryParameters,
		                      ISet<EntityKey> resultingEntityKeys)
		{
			this.resultingEntityKeys = resultingEntityKeys;
			this.queryParameters = queryParameters;
			this.loadable = loadable;
			this.alias = alias;

			queryString = queryParameters.ProcessedSql.GetSubselectString();
		}
예제 #16
0
		public SubselectFetch(string alias, ILoadable loadable, QueryParameters queryParameters,
		                      ISet<EntityKey> resultingEntityKeys, IDictionary<string, int[]> namedParameterLocMap)
		{
			this.resultingEntityKeys = resultingEntityKeys;
			this.queryParameters = queryParameters;
			this.namedParameterLocMap = namedParameterLocMap;
			this.loadable = loadable;
			this.alias = alias;

			queryString = queryParameters.FilteredSQL.GetSubselectString();
		}
예제 #17
0
		protected virtual void BindParameters(IDbCommand command, QueryParameters[] queryParameters)
		{
			int colIndex = 0;

			for (int queryIndex = 0; queryIndex < resultSetsCount; queryIndex++)
			{
				int limitParameterSpan = BindLimitParametersFirstIfNeccesary(command, queryParameters[queryIndex], colIndex);
				colIndex = BindQueryParameters(command, queryParameters[queryIndex], colIndex + limitParameterSpan);
				colIndex += BindLimitParametersLastIfNeccesary(command, queryParameters[queryIndex], colIndex);
			}
		}
		public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session)
		{
			string backTrackId = GetIdsForBackTrack(session.Factory).First(); // just the first because IType suppose the oders in certain sequence

			// The same filterName-parameterName can appear more than once in the whole query
			object value = session.GetFilterParameterValue(filterParameterFullName);
			foreach (int position in multiSqlQueryParametersList.GetEffectiveParameterLocations(backTrackId))
			{
				ExpectedType.NullSafeSet(command, value, position, session);
			}
		}
		public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session)
		{
			// The QuerySkipParameterSpecification is unique so we can use multiSqlQueryParametersList
			var effectiveParameterLocations = multiSqlQueryParametersList.GetEffectiveParameterLocations(limitParametersNameForThisQuery).ToArray();
			if (effectiveParameterLocations.Length > 0)
			{
				// if the dialect does not support variable limits the parameter may was removed
				int value = Loader.Loader.GetOffsetUsingDialect(queryParameters.RowSelection, session.Factory.Dialect) ?? queryParameters.RowSelection.FirstRow;
				int position = effectiveParameterLocations[0];
				type.NullSafeSet(command, value, position, session);
			}
		}
		public override void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session)
		{
			IType type = ExpectedType;
			object value = queryParameters.PositionalParameterValues[hqlPosition];

			string backTrackId = GetIdsForBackTrack(session.Factory).First(); // just the first because IType suppose the oders in certain sequence
			// an HQL positional parameter can appear more than once because a custom HQL-Function can duplicate it
			foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId))
			{
				type.NullSafeSet(command, GetPagingValue(value, session.Factory.Dialect, queryParameters), position + singleSqlParametersOffset, session);
			}
		}
예제 #21
0
		public override int Execute(QueryParameters parameters, ISessionImplementor session)
		{
			CoordinateSharedCacheCleanup(session);

			IDbCommand st = null;
			RowSelection selection = parameters.RowSelection;

			try
			{
				try
				{
					CheckParametersExpectedType(parameters); // NH Different behavior (NH-1898)
					var parameterTypes = new List<SqlType>(Parameters.Count);
					foreach (var parameterSpecification in Parameters)
					{
						if (parameterSpecification.ExpectedType == null)
						{
							throw new QuerySyntaxException("Can't determine SqlType of parameter " + parameterSpecification.RenderDisplayInfo()+"\n Possible cause: wrong case-sensitive property-name.");
						}
						parameterTypes.AddRange(parameterSpecification.ExpectedType.SqlTypes(Factory));
					}
					st = session.Batcher.PrepareCommand(CommandType.Text, sql, parameterTypes.ToArray());
					IEnumerator<IParameterSpecification> paramSpecifications = Parameters.GetEnumerator();
					// NH Different behavior: The inital value is 0 (initialized to 1 in JAVA)
					int pos = 0;
					while (paramSpecifications.MoveNext())
					{
						var paramSpec = paramSpecifications.Current;
						pos += paramSpec.Bind(st, parameters, session, pos);
					}
					if (selection != null)
					{
						if (selection.Timeout != RowSelection.NoValue)
						{
							st.CommandTimeout = selection.Timeout;
						}
					}
					return session.Batcher.ExecuteNonQuery(st);
				}
				finally
				{
					if (st != null)
					{
						session.Batcher.CloseCommand(st, null);
					}
				}
			}
			catch (DbException sqle)
			{
				throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle,
																 "could not execute update query", sql);
			}
		}
		public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session)
		{
			// The QueryTakeParameterSpecification is unique so we can use multiSqlQueryParametersList
			var effectiveParameterLocations = multiSqlQueryParametersList.GetEffectiveParameterLocations(limitParametersNameForThisQuery).ToArray();
			if (effectiveParameterLocations.Any())
			{
				// if the dialect does not support variable limits the parameter may was removed
				int value = queryParameters.RowSelection.MaxRows;
				int position = effectiveParameterLocations.Single();
				type.NullSafeSet(command, value, position, session);
			}
		}
예제 #23
0
		public virtual IDataReader GetReader(QueryParameters[] queryParameters, int? commandTimeout)
		{
			SqlType[] sqlTypes = types.ToArray();
			var command= batcher.PrepareQueryCommand(CommandType.Text, sqlString, sqlTypes);
			if(commandTimeout.HasValue)
			{
				command.CommandTimeout = commandTimeout.Value;				
			}
			log.Info(command.CommandText);

			BindParameters(command, queryParameters);
			return new BatcherDataReaderWrapper(batcher, command);
		}
		protected object GetPagingValue(object value, Dialect.Dialect dialect, QueryParameters queryParameters)
		{
			if (isTakeParameter)
			{
				int skipParameterValue = 0;

				if (skipParameter != null)
					skipParameterValue = skipParameter.GetSkipValue(queryParameters);

				return dialect.GetLimitValue(skipParameterValue , (int)value);
			}

			if (isSkipParameter)
				return dialect.GetOffsetValue((int)value);

			return value;
		}
		public IList GetResultFromQueryCache(ISessionImplementor session, QueryParameters queryParameters,
											 ISet<string> querySpaces, IQueryCache queryCache, QueryKey key)
		{
			if (!queryParameters.ForceCacheRefresh)
			{
				IList list =
					queryCache.Get(key, new ICacheAssembler[] {this}, queryParameters.NaturalKeyLookup, querySpaces, session);
				//we had to wrap the query results in another list in order to save all
				//the queries in the same bucket, now we need to do it the other way around.
				if (list != null)
				{
					list = (IList) list[0];
				}
				return list;
			}
			return null;
		}
예제 #26
0
		public override int Execute(QueryParameters parameters, ISessionImplementor session)
		{
			CoordinateSharedCacheCleanup(session);

			IDbCommand st = null;
			RowSelection selection = parameters.RowSelection;

			try
			{
				try
				{
					CheckParametersExpectedType(parameters); // NH Different behavior (NH-1898)

					var sqlQueryParametersList = sql.GetParameters().ToList();
					SqlType[] parameterTypes = Parameters.GetQueryParameterTypes(sqlQueryParametersList, session.Factory);

					st = session.Batcher.PrepareCommand(CommandType.Text, sql, parameterTypes);
					foreach (var parameterSpecification in Parameters)
					{
						parameterSpecification.Bind(st, sqlQueryParametersList, parameters, session);
					}

					if (selection != null)
					{
						if (selection.Timeout != RowSelection.NoValue)
						{
							st.CommandTimeout = selection.Timeout;
						}
					}
					return session.Batcher.ExecuteNonQuery(st);
				}
				finally
				{
					if (st != null)
					{
						session.Batcher.CloseCommand(st, null);
					}
				}
			}
			catch (DbException sqle)
			{
				throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle,
																 "could not execute update query", sql);
			}
		}
		public SubselectOneToManyLoader(IQueryableCollection persister, SqlString subquery, ICollection<EntityKey> entityKeys,
		                                QueryParameters queryParameters, IDictionary<string, int[]> namedParameterLocMap,
		                                ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters)
			: base(persister, 1, subquery, factory, enabledFilters)
		{
			keys = new object[entityKeys.Count];
			int i = 0;
			foreach (EntityKey entityKey in entityKeys)
			{
				keys[i++] = entityKey.Identifier;
			}

			namedParameters = queryParameters.NamedParameters;
			// NH Different behavior: to deal with positionslParameter+NamedParameter+ParameterOfFilters
			types = queryParameters.PositionalParameterTypes;
			values = queryParameters.PositionalParameterValues;
			this.namedParameterLocMap = namedParameterLocMap;
		}
예제 #28
0
        public SubselectCollectionLoader(
            IQueryableCollection persister,
            SqlString subquery,
            ICollection entityKeys,
            QueryParameters queryParameters,
            IDictionary namedParameterLocMap,
            ISessionFactoryImplementor factory,
            IDictionary<string, IFilter> enabledFilters)
            : base(persister, 1, subquery, factory, enabledFilters)
        {
            keys = new object[entityKeys.Count];
            int i = 0;
            foreach (EntityKey entityKey in entityKeys)
            {
                keys[i++] = entityKey.Identifier;
            }

            namedParameters = queryParameters.NamedParameters;
            types = queryParameters.FilteredPositionalParameterTypes;
            values = queryParameters.FilteredPositionalParameterValues;
            this.namedParameterLocMap = namedParameterLocMap;
        }
예제 #29
0
파일: QueryKey.cs 프로젝트: ray2006/WCell
		/// <summary>
		/// Initializes a new instance of the <see cref="QueryKey"/> class.
		/// </summary>
		/// <param name="factory">the session factory for this query key, required to get the identifiers of entities that are used as values.</param>
		/// <param name="queryString">The query string.</param>
		/// <param name="queryParameters">The query parameters.</param>
		/// <param name="filters">The filters.</param>
		public QueryKey(ISessionFactoryImplementor factory, SqlString queryString, QueryParameters queryParameters,
		                ISet filters)
		{
			this.factory = factory;
			sqlQueryString = queryString;
			types = queryParameters.PositionalParameterTypes;
			values = queryParameters.PositionalParameterValues;

			RowSelection selection = queryParameters.RowSelection;
			if (selection != null)
			{
				firstRow = selection.FirstRow;
				maxRows = selection.MaxRows;
			}
			else
			{
				firstRow = RowSelection.NoValue;
				maxRows = RowSelection.NoValue;
			}
			namedParameters = queryParameters.NamedParameters;
			this.filters = filters;
			this.customTransformer = queryParameters.ResultTransformer;
			this.hashCode = ComputeHashCode();
		}
예제 #30
0
		/// <summary>
		/// Initializes a new instance of the <see cref="QueryKey"/> class.
		/// </summary>
		/// <param name="factory">the session factory for this query key, required to get the identifiers of entities that are used as values.</param>
		/// <param name="queryString">The query string.</param>
		/// <param name="queryParameters">The query parameters.</param>
		/// <param name="filters">The filters.</param>
		public QueryKey(ISessionFactoryImplementor factory, SqlString queryString, QueryParameters queryParameters,
						ISet<FilterKey> filters)
		{
			_factory = factory;
			_sqlQueryString = queryString;
			_types = queryParameters.PositionalParameterTypes;
			_values = queryParameters.PositionalParameterValues;

			RowSelection selection = queryParameters.RowSelection;
			if (selection != null)
			{
				_firstRow = selection.FirstRow;
				_maxRows = selection.MaxRows;
			}
			else
			{
				_firstRow = RowSelection.NoValue;
				_maxRows = RowSelection.NoValue;
			}
			_namedParameters = queryParameters.NamedParameters;
			_filters = filters;
			_customTransformer = queryParameters.ResultTransformer;
			_hashCode = ComputeHashCode();
		}