public SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary <string, IFilter> enabledFilters) { string entityName = criteriaQuery.GetEntityName(criteria, propertyName); string actualPropertyName = criteriaQuery.GetPropertyName(propertyName); string sqlAlias = criteriaQuery.GetSQLAlias(criteria, propertyName); ISessionFactoryImplementor factory = criteriaQuery.Factory; IQueryableCollection collectionPersister = GetQueryableCollection(entityName, actualPropertyName, factory); string[] collectionKeys = collectionPersister.KeyColumnNames; string[] ownerKeys = ((ILoadable)factory.GetEntityPersister(entityName)).IdentifierColumnNames; StringBuilder innerSelect = new StringBuilder(); innerSelect.Append("(select 1 from ") .Append(collectionPersister.TableName) .Append(" where ") .Append( new ConditionalFragment().SetTableAlias(sqlAlias).SetCondition(ownerKeys, collectionKeys).ToSqlStringFragment()); if (collectionPersister.HasWhere) { innerSelect.Append(" and (") .Append(collectionPersister.GetSQLWhereString(collectionPersister.TableName)) .Append(") "); } innerSelect.Append(")"); return(new SqlString(new string[] { ExcludeEmpty ? "exists" : "not exists", innerSelect.ToString() })); }
public OneToManyLoader( IQueryableCollection oneToManyPersister, ISessionFactoryImplementor session, IDictionary enabledFilters) : this(oneToManyPersister, 1, session, enabledFilters) { }
public override void PrepareForDot(string propertyName) { FromElement fromElement = FromElement; if (fromElement == null) { throw new InvalidOperationException("No FROM element for index operator!"); } IQueryableCollection queryableCollection = fromElement.QueryableCollection; if (queryableCollection != null && !queryableCollection.IsOneToMany) { FromReferenceNode collectionNode = ( FromReferenceNode )GetChild(0); String path = collectionNode.Path + "[]." + propertyName; if (Log.IsDebugEnabled) { Log.Debug("Creating join for many-to-many elements for " + path); } FromElementFactory factory = new FromElementFactory(fromElement.FromClause, fromElement, path); // This will add the new from element to the origin. FromElement elementJoin = factory.CreateElementJoin(queryableCollection); FromElement = elementJoin; } }
public BasicCollectionJoinWalker( IQueryableCollection collectionPersister, int batchSize, SqlString subquery, ISessionFactoryImplementor factory, IDictionary enabledFilters) : base(factory, enabledFilters) { this.collectionPersister = collectionPersister; string alias = GenerateRootAlias(collectionPersister.Role); WalkCollectionTree(collectionPersister, alias); IList allAssociations = new ArrayList(); ArrayHelper.AddAll(allAssociations, associations); allAssociations.Add(new OuterJoinableAssociation( collectionPersister.CollectionType, null, null, alias, JoinType.LeftOuterJoin, Factory, enabledFilters )); InitPersisters(allAssociations, LockMode.None); InitStatementString(alias, batchSize, subquery); }
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; }
private void InitStatementString( IQueryableCollection persister, string alias, IList associations, int batchSize, ISessionFactoryImplementor factory ) { Suffixes = GenerateSuffixes( associations.Count ); SqlStringBuilder whereString = WhereString( factory, alias, persister.KeyColumnNames, persister.KeyType, batchSize ); if( persister.HasWhere ) { whereString .Add( " and " ) .Add( persister.GetSQLWhereString( alias ) ); } JoinFragment ojf = MergeOuterJoins( associations ); SqlSelectBuilder select = new SqlSelectBuilder( factory ) .SetSelectClause( persister.SelectFragment( alias ).Append( SelectString( associations, factory ) ).ToString() ) .SetFromClause( persister.TableName, alias ) .SetWhereClause( whereString.ToSqlString() ) .SetOuterJoins( ojf.ToFromFragmentString, ojf.ToWhereFragmentString ); if( persister.HasOrdering ) { select.SetOrderByClause( persister.GetSQLOrderByString( alias ) ); } SqlString = select.ToSqlString(); }
private static void AddImpliedFromToFromNode(IASTNode fromClause, string collectionRole, ISessionFactoryImplementor factory) { SessionFactoryHelperExtensions _sessionFactoryHelper = new SessionFactoryHelperExtensions(factory); IQueryableCollection persister = _sessionFactoryHelper.GetCollectionPersister(collectionRole); IType collectionElementType = persister.ElementType; if (!collectionElementType.IsEntityType) { throw new QueryException("collection of values in filter: this"); } string collectionElementEntityName = persister.ElementPersister.EntityName; ITreeAdaptor adaptor = new ASTTreeAdaptor(); IASTNode fromElement = (IASTNode)adaptor.Create(HqlParser.FILTER_ENTITY, collectionElementEntityName); IASTNode alias = (IASTNode)adaptor.Create(HqlParser.ALIAS, "this"); fromClause.AddChild(fromElement); fromClause.AddChild(alias); // Show the modified AST. if (log.IsDebugEnabled()) { log.Debug("AddImpliedFormToFromNode() : Filter - Added 'this' as a from element..."); } }
/// <summary> /// Add on association (one-to-one, many-to-one, or a collection) to a list /// of associations to be fetched by outerjoin /// </summary> private void AddAssociationToJoinTree(IAssociationType type, string[] aliasedLhsColumns, string alias, string path, int currentDepth, JoinType joinType) { IJoinable joinable = type.GetAssociatedJoinable(Factory); string subalias = GenerateTableAlias(associations.Count + 1, path, joinable); OuterJoinableAssociation assoc = new OuterJoinableAssociation(type, alias, aliasedLhsColumns, subalias, joinType, GetWithClause(path), Factory, enabledFilters); assoc.ValidateJoin(path); AddAssociation(subalias, assoc); int nextDepth = currentDepth + 1; if (!joinable.IsCollection) { IOuterJoinLoadable pjl = joinable as IOuterJoinLoadable; if (pjl != null) { WalkEntityTree(pjl, subalias, path, nextDepth); } } else { IQueryableCollection qc = joinable as IQueryableCollection; if (qc != null) { WalkCollectionTree(qc, subalias, path, nextDepth); } } }
public BasicCollectionLoader( IQueryableCollection collectionPersister, ISessionFactoryImplementor session, IDictionary<string, IFilter> enabledFilters) : this(collectionPersister, 1, session, enabledFilters) { }
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; }
private void InitStatementString(IQueryableCollection persister, string alias, IList associations, int batchSize, ISessionFactoryImplementor factory) { Suffixes = GenerateSuffixes(associations.Count); SqlStringBuilder whereString = WhereString(factory, alias, persister.KeyColumnNames, persister.KeyType, batchSize); if (persister.HasWhere) { whereString .Add(" and ") .Add(persister.GetSQLWhereString(alias)); } JoinFragment ojf = MergeOuterJoins(associations); SqlSelectBuilder select = new SqlSelectBuilder(factory) .SetSelectClause( persister.SelectFragment(alias).Append( SelectString(associations, factory)).ToString() ) .SetFromClause(persister.TableName, alias) .SetWhereClause(whereString.ToSqlString()) .SetOuterJoins( ojf.ToFromFragmentString, ojf.ToWhereFragmentString ); if (persister.HasOrdering) { select.SetOrderByClause(persister.GetSQLOrderByString(alias)); } SqlString = select.ToSqlString(); }
protected void InitPersisters(IList <OuterJoinableAssociation> associations, LockMode lockMode) { int joins = CountEntityPersisters(associations); int collections = CountCollectionPersisters(associations); collectionOwners = collections == 0 ? null : new int[collections]; collectionPersisters = collections == 0 ? null : new ICollectionPersister[collections]; collectionSuffixes = BasicLoader.GenerateSuffixes(joins + 1, collections); persisters = new ILoadable[joins]; aliases = new String[joins]; owners = new int[joins]; ownerAssociationTypes = new EntityType[joins]; lockModeArray = ArrayHelper.Fill(lockMode, joins); int i = 0; int j = 0; foreach (OuterJoinableAssociation oj in associations) { if (!oj.IsCollection) { persisters[i] = (ILoadable)oj.Joinable; aliases[i] = oj.RHSAlias; owners[i] = oj.GetOwner(associations); ownerAssociationTypes[i] = (EntityType)oj.JoinableType; i++; } else { IQueryableCollection collPersister = (IQueryableCollection)oj.Joinable; if (oj.JoinType == JoinType.LeftOuterJoin) { //it must be a collection fetch collectionPersisters[j] = collPersister; collectionOwners[j] = oj.GetOwner(associations); j++; } if (collPersister.IsOneToMany) { persisters[i] = (ILoadable)collPersister.ElementPersister; aliases[i] = oj.RHSAlias; i++; } } } if (ArrayHelper.IsAllNegative(owners)) { owners = null; } if (collectionOwners != null && ArrayHelper.IsAllNegative(collectionOwners)) { collectionOwners = null; } }
public BasicCollectionLoader( IQueryableCollection collectionPersister, int batchSize, ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters) : this(collectionPersister, batchSize, null, factory, enabledFilters) { }
public FromElement CreateCollectionElementsJoin(IQueryableCollection queryableCollection, String collectionName) { JoinSequence collectionJoinSequence = _fromClause.SessionFactoryHelper.CreateCollectionJoinSequence(queryableCollection, collectionName); _queryableCollection = queryableCollection; return(CreateCollectionJoin(collectionJoinSequence, null)); }
public OneToManyLoader( IQueryableCollection oneToManyPersister, int batchSize, ISessionFactoryImplementor factory, IDictionary enabledFilters) : this(oneToManyPersister, batchSize, null, factory, enabledFilters) { }
/// <summary> /// For a composite element, add to a list of associations to be fetched by outerjoin /// </summary> private void WalkCompositeElementTree(IAbstractComponentType compositeType, string[] cols, IQueryableCollection persister, string alias, string path, string subPathAlias, int currentDepth) { IType[] types = compositeType.Subtypes; string[] propertyNames = compositeType.PropertyNames; int begin = 0; for (int i = 0; i < types.Length; i++) { int length = types[i].GetColumnSpan(factory); string[] lhsColumns = ArrayHelper.Slice(cols, begin, length); if (types[i].IsAssociationType) { IAssociationType associationType = types[i] as IAssociationType; // simple, because we can't have a one-to-one or collection // (or even a property-ref) in a composite element: string[] aliasedLhsColumns = StringHelper.Qualify(alias, lhsColumns); string subpath = SubPath(path, propertyNames[i]); bool[] propertyNullability = compositeType.PropertyNullability; var joinType = GetJoinType( associationType, compositeType.GetFetchMode(i), subpath, alias, persister.TableName, lhsColumns, propertyNullability == null || propertyNullability[i], currentDepth, compositeType.GetCascadeStyle(i)); AddAssociationToJoinTreeIfNecessary( associationType, aliasedLhsColumns, alias, subpath, subPathAlias, currentDepth, joinType); } else if (types[i].IsComponentType) { string subpath = SubPath(path, propertyNames[i]); WalkCompositeElementTree( (IAbstractComponentType)types[i], lhsColumns, persister, alias, subpath, subPathAlias, currentDepth); } begin += length; } }
/// <summary> /// For a collection role, return a list of associations to be fetched by outerjoin /// </summary> private void WalkCollectionTree(IQueryableCollection persister, string alias, string path, string subPathAlias, int currentDepth) { if (persister.IsOneToMany) { WalkEntityTree((IOuterJoinLoadable)persister.ElementPersister, alias, path, currentDepth); } else { IType type = persister.ElementType; if (type.IsAssociationType) { // a many-to-many // decrement currentDepth here to allow join across the association table // without exceeding MAX_FETCH_DEPTH (i.e. the "currentDepth - 1" bit) IAssociationType associationType = (IAssociationType)type; string[] aliasedLhsColumns = persister.GetElementColumnNames(alias); string[] lhsColumns = persister.ElementColumnNames; // if the current depth is 0, the root thing being loaded is the // many-to-many collection itself. Here, it is alright to use // an inner join... bool useInnerJoin = currentDepth == 0; var joinType = GetJoinType( associationType, persister.FetchMode, path, subPathAlias, persister.TableName, lhsColumns, !useInnerJoin, currentDepth - 1, null); AddAssociationToJoinTreeIfNecessary( associationType, aliasedLhsColumns, alias, path, subPathAlias, currentDepth - 1, joinType); } else if (type.IsComponentType) { WalkCompositeElementTree( (IAbstractComponentType)type, persister.ElementColumnNames, persister, alias, path, subPathAlias, currentDepth); } } }
private bool IsManyToManyRoot(IJoinable joinable) { if (joinable != null && joinable.IsCollection) { IQueryableCollection persister = (IQueryableCollection)joinable; return(persister.IsManyToMany); } return(false); }
protected virtual void InitializeFromWalker(IQueryableCollection oneToManyPersister, SqlString subquery, int batchSize, IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory) { JoinWalker walker = new OneToManyJoinWalker(oneToManyPersister, batchSize, subquery, factory, enabledFilters); InitFromWalker(walker); PostInstantiate(); log.Debug("Static select for one-to-many " + oneToManyPersister.Role + ": " + SqlString); }
protected void InitClassPersisters(IList associations) { int joins = CountClassPersisters(associations); collectionOwner = -1; // if no collection found classPersisters = new ILoadable[joins + 1]; Owners = new int[joins + 1]; aliases = new string[joins + 1]; lockModeArray = CreateLockModeArray(joins + 1, LockMode.None); int i = 0; foreach (OuterJoinableAssociation oj in associations) { object subpersister = oj.Joinable; if (subpersister is ILoadable) { classPersisters[i] = ( ILoadable )subpersister; Owners[i] = ToOwner(oj, joins, oj.IsOneToOne); aliases[i] = oj.Subalias; if (oj.JoinType == JoinType.InnerJoin) { AddAllToPropertySpaces(classPersisters[i].PropertySpaces); } i++; } else { IQueryableCollection collPersister = ( IQueryableCollection )subpersister; // TODO: ?? suppress initialization of collections with a where condition if (oj.JoinType == JoinType.LeftOuterJoin) { collectionPersister = collPersister; collectionOwner = ToOwner(oj, joins, true); } else { AddToPropertySpaces(collPersister.CollectionSpace); } if (collPersister.IsOneToMany) { classPersisters[i] = ( ILoadable )collPersister.ElementPersister; aliases[i] = oj.Subalias; i++; } } } classPersisters[joins] = persister; Owners[joins] = -1; aliases[joins] = alias; if (ArrayHelper.IsAllNegative(Owners)) { Owners = null; } }
protected virtual void InitializeFromWalker(IQueryableCollection oneToManyPersister, SqlString subquery, int batchSize, IDictionary <string, IFilter> enabledFilters, ISessionFactoryImplementor factory) { JoinWalker walker = new OneToManyJoinWalker(oneToManyPersister, batchSize, subquery, factory, enabledFilters); InitFromWalker(walker); PostInstantiate(); log.Debug("Static select for one-to-many {0}: {1}", oneToManyPersister.Role, SqlString); }
protected virtual void InitializeFromWalker(IQueryableCollection collectionPersister, SqlString subquery, int batchSize, IDictionary <string, IFilter> enabledFilters, ISessionFactoryImplementor factory) { JoinWalker walker = new BasicCollectionJoinWalker(collectionPersister, batchSize, subquery, factory, enabledFilters); InitFromWalker(walker); PostInstantiate(); log.Debug("Static select for collection " + collectionPersister.Role + ": " + SqlString); }
public FromElement CreateElementJoin(IQueryableCollection queryableCollection) { _implied = true; //TODO: always true for now, but not if we later decide to support elements() in the from clause _inElementsFunction = true; IType elementType = queryableCollection.ElementType; if (!elementType.IsEntityType) { throw new InvalidOperationException("Cannot create element join for a collection of non-entities!"); } _queryableCollection = queryableCollection; SessionFactoryHelperExtensions sfh = _fromClause.SessionFactoryHelper; IEntityPersister entityPersister = queryableCollection.ElementPersister; string tableAlias = _fromClause.AliasGenerator.CreateName(entityPersister.EntityName); string associatedEntityName = entityPersister.EntityName; IEntityPersister targetEntityPersister = sfh.RequireClassPersister(associatedEntityName); // Create the FROM element for the target (the elements of the collection). FromElement destination = CreateAndAddFromElement( associatedEntityName, _classAlias, targetEntityPersister, (EntityType)queryableCollection.ElementType, tableAlias ); // If the join is implied, then don't include sub-classes on the element. if (_implied) { destination.IncludeSubclasses = false; } _fromClause.AddCollectionJoinFromElementByPath(_path, destination); // origin.addDestination(destination); // Add the query spaces. _fromClause.Walker.AddQuerySpaces(entityPersister.QuerySpaces); CollectionType type = queryableCollection.CollectionType; string role = type.Role; string roleAlias = _origin.TableAlias; string[] targetColumns = sfh.GetCollectionElementColumns(role, roleAlias); IAssociationType elementAssociationType = sfh.GetElementAssociationType(type); // Create the join element under the from element. JoinSequence joinSequence = sfh.CreateJoinSequence(_implied, elementAssociationType, tableAlias, JoinType.InnerJoin, targetColumns); FromElement elem = InitializeJoin(_path, destination, joinSequence, targetColumns, _origin, false); elem.UseFromFragment = true; // The associated entity is implied, but it must be included in the FROM. elem.CollectionTableAlias = roleAlias; // The collection alias is the role. return(elem); }
protected BasicCollectionLoader(IQueryableCollection collectionPersister, int batchSize, SqlString subquery, ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters) : base(collectionPersister, factory, enabledFilters) { JoinWalker walker = new BasicCollectionJoinWalker(collectionPersister, batchSize, subquery, factory, enabledFilters); InitFromWalker(walker); PostInstantiate(); log.Debug("Static select for collection " + collectionPersister.Role + ": " + SqlString); }
public void AddManyToManyJoin(JoinFragment outerjoin, IQueryableCollection collection) { string manyToManyFilter = collection.GetManyToManyFilterFragment(rhsAlias, enabledFilters); string condition = string.Empty.Equals(manyToManyFilter) ? on : string.Empty.Equals(on) ? manyToManyFilter : on + " and " + manyToManyFilter; outerjoin.AddJoin(joinable.TableName, rhsAlias, lhsColumns, rhsColumns, joinType, condition); outerjoin.AddJoins(joinable.FromJoinFragment(rhsAlias, false, true), joinable.WhereJoinFragment(rhsAlias, false, true)); }
public bool IsManyToManyWith(OuterJoinableAssociation other) { if (joinable.IsCollection) { IQueryableCollection persister = (IQueryableCollection)joinable; if (persister.IsManyToMany) { return(persister.ElementType == other.JoinableType); } } return(false); }
public OneToManyLoader(IQueryableCollection oneToManyPersister, int batchSize, SqlString subquery, ISessionFactoryImplementor factory, IDictionary <string, IFilter> enabledFilters) : base(oneToManyPersister, factory, enabledFilters) { JoinWalker walker = new OneToManyJoinWalker(oneToManyPersister, batchSize, subquery, factory, enabledFilters); InitFromWalker(walker); PostInstantiate(); log.Debug("Static select for one-to-many " + oneToManyPersister.Role + ": " + SqlString); }
public void AddManyToManyJoin(JoinFragment outerjoin, IQueryableCollection collection) { string manyToManyFilter = collection.GetManyToManyFilterFragment(rhsAlias, enabledFilters); SqlString condition = string.Empty.Equals(manyToManyFilter) ? on : SqlStringHelper.IsEmpty(on) ? new SqlString(manyToManyFilter) : on.Append(" and ").Append(manyToManyFilter); outerjoin.AddJoin(joinable.TableName, rhsAlias, lhsColumns, rhsColumns, joinType, condition); outerjoin.AddJoins(joinable.FromJoinFragment(rhsAlias, false, true), joinable.WhereJoinFragment(rhsAlias, false, true)); }
/// <summary> /// Create a join sequence rooted at the given collection. /// </summary> /// <param name="collPersister">The persister for the collection at which the join should be rooted.</param> /// <param name="collectionName">The alias to use for qualifying column references.</param> /// <returns>The generated join sequence.</returns> public JoinSequence CreateCollectionJoinSequence(IQueryableCollection collPersister, String collectionName) { JoinSequence joinSequence = CreateJoinSequence(); joinSequence.SetRoot(collPersister, collectionName); joinSequence.SetUseThetaStyle(true); // TODO: figure out how this should be set. /////////////////////////////////////////////////////////////////////////////// // This was the reason for failures regarding INDEX_OP and subclass joins on // theta-join dialects; not sure what behaviour we were trying to emulate ;) // joinSequence = joinSequence.getFromPart(); // Emulate the old addFromOnly behavior. return joinSequence; }
IASTNode CreateFromFilterElement(IASTNode filterEntity, IASTNode alias) { var fromElementFound = true; var fromElement = _currentFromClause.GetFromElement(alias.Text) ?? _currentFromClause.GetFromElementByClassName(filterEntity.Text); if (fromElement == null) { fromElementFound = false; fromElement = _currentFromClause.AddFromElement(filterEntity.Text, alias); } FromClause fromClause = fromElement.FromClause; IQueryableCollection persister = _sessionFactoryHelper.GetCollectionPersister(_collectionFilterRole); // Get the names of the columns used to link between the collection // owner and the collection elements. String[] keyColumnNames = persister.KeyColumnNames; String fkTableAlias = persister.IsOneToMany ? fromElement.TableAlias : fromClause.AliasGenerator.CreateName(_collectionFilterRole); JoinSequence join = _sessionFactoryHelper.CreateJoinSequence(); join.SetRoot(persister, fkTableAlias); if (!persister.IsOneToMany) { join.AddJoin((IAssociationType)persister.ElementType, fromElement.TableAlias, JoinType.InnerJoin, persister.GetElementColumnNames(fkTableAlias)); } join.AddCondition(fkTableAlias, keyColumnNames, " = ", true); fromElement.JoinSequence = join; fromElement.Filter = true; if (log.IsDebugEnabled()) { log.Debug("createFromFilterElement() : processed filter FROM element."); } if (fromElementFound) { return((IASTNode)adaptor.Nil()); } return(fromElement); }
public CollectionLoader( IQueryableCollection persister, int batchSize, ISessionFactoryImplementor factory ) : base( factory.Dialect ) { this.collectionPersister = persister; this.keyType = persister.KeyType; string alias = GenerateRootAlias( persister.Role ); IList associations = WalkCollectionTree( persister, alias, factory ); InitStatementString( persister, alias, associations, batchSize, factory ); InitClassPersisters( associations ); PostInstantiate(); }
public CollectionLoader(IQueryableCollection persister, int batchSize, ISessionFactoryImplementor factory) : base(factory.Dialect) { this.collectionPersister = persister; this.keyType = persister.KeyType; string alias = GenerateRootAlias(persister.Role); IList associations = WalkCollectionTree(persister, alias, factory); InitStatementString(persister, alias, associations, batchSize, factory); InitClassPersisters(associations); PostInstantiate(); }
private void PrepareForIndex(QueryTranslator q) { IQueryableCollection collPersister = q.GetCollectionPersister(collectionRole); if (!collPersister.HasIndex) { throw new QueryException("unindexed collection before []"); } string[] indexCols = collPersister.IndexColumnNames; if (indexCols.Length != 1) { throw new QueryException("composite-index appears in []: " + path); } string[] keyCols = collPersister.KeyColumnNames; JoinFragment ojf = q.CreateJoinFragment(useThetaStyleJoin); ojf.AddCrossJoin(collPersister.TableName, collectionName); ojf.AddFromFragmentString(join.ToFromFragmentString); if (collPersister.IsOneToMany) { IQueryable persister = (IQueryable)collPersister.ElementPersister; ojf.AddJoins( ((IJoinable)persister).FromJoinFragment(collectionName, true, false), ((IJoinable)persister).WhereJoinFragment(collectionName, true, false) ); } if (!continuation) { AddJoin(collPersister.TableName, collectionName, keyCols); } join.AddCondition(collectionName, indexCols, " = "); string[] eltCols = collPersister.ElementColumnNames; CollectionElement elem = new CollectionElement(); elem.ElementColumns = StringHelper.Qualify(collectionName, eltCols); elem.Type = collPersister.ElementType; elem.IsOneToMany = collPersister.IsOneToMany; elem.Alias = collectionName; elem.Join = join; collectionElements.Add(elem); //addlast SetExpectingCollectionIndex(); q.AddCollection(collectionName, collectionRole); q.AddJoin(collectionName, ojf); }
public CollectionElementLoader(IQueryableCollection collectionPersister, ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters) : base(factory, enabledFilters) { keyType = collectionPersister.KeyType; indexType = collectionPersister.IndexType; persister = (IOuterJoinLoadable)collectionPersister.ElementPersister; entityName = persister.EntityName; JoinWalker walker = new EntityJoinWalker(persister, ArrayHelper.Join(collectionPersister.KeyColumnNames, collectionPersister.IndexColumnNames), 1, LockMode.None, factory, enabledFilters); InitFromWalker(walker); PostInstantiate(); log.Debug("Static select for entity " + entityName + ": " + SqlString); }
public OneToManyLoader( IQueryableCollection collPersister, int batchSize, ISessionFactoryImplementor factory ) : base( factory.Dialect ) { collectionPersister = collPersister; idType = collectionPersister.KeyType; IOuterJoinLoadable persister = ( IOuterJoinLoadable ) collPersister.ElementPersister; string alias = GenerateRootAlias( collPersister.Role ); IList associations = WalkTree( persister, alias, factory ); InitStatementString( collPersister, persister, alias, associations, batchSize, factory ); InitClassPersisters( persister, associations ); PostInstantiate(); }
public OneToManyLoader(IQueryableCollection collPersister, int batchSize, ISessionFactoryImplementor factory) : base(factory.Dialect) { collectionPersister = collPersister; idType = collectionPersister.KeyType; IOuterJoinLoadable persister = ( IOuterJoinLoadable )collPersister.ElementPersister; string alias = GenerateRootAlias(collPersister.Role); IList associations = WalkTree(persister, alias, factory); InitStatementString(collPersister, persister, alias, associations, batchSize, factory); InitClassPersisters(persister, associations); PostInstantiate(); }
public System.Type GetAssociatedClass(ISessionFactoryImplementor factory) { try { IQueryableCollection collectionPersister = (IQueryableCollection)factory.GetCollectionPersister(role); if (!collectionPersister.ElementType.IsEntityType) { throw new MappingException(string.Format("collection was not an association: {0}", collectionPersister.Role)); } return(collectionPersister.ElementPersister.MappedClass); } catch (InvalidCastException ice) { throw new MappingException("collection role is not queryable " + role, ice); } }
/// <summary> /// Get the order by string required for collection fetching /// </summary> protected SqlString OrderBy(IList <OuterJoinableAssociation> associations) { SqlStringBuilder buf = new SqlStringBuilder(); OuterJoinableAssociation last = null; foreach (OuterJoinableAssociation oj in associations) { if (oj.JoinType == JoinType.LeftOuterJoin) { if (oj.Joinable.IsCollection) { IQueryableCollection queryableCollection = (IQueryableCollection)oj.Joinable; if (queryableCollection.HasOrdering) { string orderByString = queryableCollection.GetSQLOrderByString(oj.RHSAlias); buf.Add(orderByString).Add(StringHelper.CommaSpace); } } else { // it might still need to apply a collection ordering based on a // many-to-many defined order-by... if (last != null && last.Joinable.IsCollection) { IQueryableCollection queryableCollection = (IQueryableCollection)last.Joinable; if (queryableCollection.IsManyToMany && last.IsManyToManyWith(oj)) { if (queryableCollection.HasManyToManyOrdering) { string orderByString = queryableCollection.GetManyToManyOrderByString(oj.RHSAlias); buf.Add(orderByString).Add(StringHelper.CommaSpace); } } } } } last = oj; } if (buf.Count > 0) { buf.RemoveAt(buf.Count - 1); } return(buf.ToSqlString()); }
public ComponentCollectionCriteriaInfoProvider(IQueryableCollection persister) { this.persister = persister; if (!persister.ElementType.IsComponentType) { throw new ArgumentException("persister for role " + persister.Role + " is not a collection-of-component"); } var componentType = (ComponentType)persister.ElementType; var names = componentType.PropertyNames; var types = componentType.Subtypes; for (var i = 0; i < names.Length; i++) { subTypes.Add(names[i], types[i]); } }
public ComponentCollectionCriteriaInfoProvider(IQueryableCollection persister) { this.persister = persister; if (!persister.ElementType.IsComponentType) { throw new ArgumentException("persister for role " + persister.Role + " is not a collection-of-component"); } var componentType = (IAbstractComponentType) persister.ElementType; string[] names = componentType.PropertyNames; IType[] types = componentType.Subtypes; for (int i = 0; i < names.Length; i++) { subTypes.Add(names[i], types[i]); } }
public OneToManyJoinWalker(IQueryableCollection oneToManyPersister, int batchSize, SqlString subquery, ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters) : base(factory, enabledFilters) { this.oneToManyPersister = oneToManyPersister; IOuterJoinLoadable elementPersister = (IOuterJoinLoadable) oneToManyPersister.ElementPersister; string alias = GenerateRootAlias(oneToManyPersister.Role); WalkEntityTree(elementPersister, alias); IList<OuterJoinableAssociation> allAssociations = new List<OuterJoinableAssociation>(associations); allAssociations.Add( new OuterJoinableAssociation(oneToManyPersister.CollectionType, null, null, alias, JoinType.LeftOuterJoin, null, Factory, new CollectionHelper.EmptyMapClass<string, IFilter>())); InitPersisters(allAssociations, LockMode.None); InitStatementString(elementPersister, alias, batchSize, subquery); }
public string GetAssociatedEntityName(ISessionFactoryImplementor factory) { try { IQueryableCollection collectionPersister = (IQueryableCollection)factory.GetCollectionPersister(role); if (!collectionPersister.ElementType.IsEntityType) { throw new MappingException("collection was not an association: " + collectionPersister.Role); } return(collectionPersister.ElementPersister.EntityName); } catch (InvalidCastException cce) { throw new MappingException("collection role is not queryable " + role, cce); } }
private void HandleElements(FromReferenceNode collectionNode, String propertyName) { FromElement collectionFromElement = collectionNode.FromElement; IQueryableCollection queryableCollection = collectionFromElement.QueryableCollection; String path = collectionNode.Path + "[]." + propertyName; Log.Debug("Creating elements for {0}", path); _fromElement = collectionFromElement; if (!collectionFromElement.IsCollectionOfValuesOrComponents) { Walker.AddQuerySpaces(queryableCollection.ElementPersister); } DataType = queryableCollection.ElementType; _selectColumns = collectionFromElement.ToColumns(_fromElement.TableAlias, propertyName, _inSelect); }
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; }
public BasicCollectionJoinWalker(IQueryableCollection collectionPersister, int batchSize, SqlString subquery, ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters) : base(factory, enabledFilters) { this.collectionPersister = collectionPersister; string alias = GenerateRootAlias(collectionPersister.Role); WalkCollectionTree(collectionPersister, alias); IList<OuterJoinableAssociation> allAssociations = new List<OuterJoinableAssociation>(associations); // NH Different behavior : passing enabledFilters instead empty-filter allAssociations.Add( new OuterJoinableAssociation(collectionPersister.CollectionType, null, null, alias, JoinType.LeftOuterJoin, null, Factory, enabledFilters)); InitPersisters(allAssociations, LockMode.None); InitStatementString(alias, batchSize, subquery); }
public BasicCollectionJoinWalker(IQueryableCollection collectionPersister, int batchSize, SqlString subquery, ISessionFactoryImplementor factory, IDictionary <string, IFilter> enabledFilters) : base(factory, enabledFilters) { this.collectionPersister = collectionPersister; string alias = GenerateRootAlias(collectionPersister.Role); WalkCollectionTree(collectionPersister, alias); IList <OuterJoinableAssociation> allAssociations = new List <OuterJoinableAssociation>(associations); // NH Different behavior : passing enabledFilters instead empty-filter allAssociations.Add( new OuterJoinableAssociation(collectionPersister.CollectionType, null, null, alias, JoinType.LeftOuterJoin, null, Factory, enabledFilters)); InitPersisters(allAssociations, LockMode.None); InitStatementString(alias, batchSize, subquery); }
public static ICollectionInitializer CreateBatchingCollectionInitializer(IQueryableCollection persister, int maxBatchSize, ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters) { if (maxBatchSize > 1) { int[] batchSizesToCreate = ArrayHelper.GetBatchSizes(maxBatchSize); Loader[] loadersToCreate = new Loader[batchSizesToCreate.Length]; for (int i = 0; i < batchSizesToCreate.Length; i++) { loadersToCreate[i] = new BasicCollectionLoader(persister, batchSizesToCreate[i], factory, enabledFilters); } return new BatchingCollectionInitializer(persister, batchSizesToCreate, loadersToCreate); } else { return new BasicCollectionLoader(persister, factory, enabledFilters); } }
public OneToManyLoader( IQueryableCollection oneToManyPersister, int batchSize, SqlString subquery, ISessionFactoryImplementor factory, IDictionary enabledFilters) : base(oneToManyPersister, factory, enabledFilters) { JoinWalker walker = new OneToManyJoinWalker( oneToManyPersister, batchSize, subquery, factory, enabledFilters ); InitFromWalker(walker); PostInstantiate(); log.Debug("Static select for one-to-many " + oneToManyPersister.Role + ": " + SqlString); }
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; }
public FromElement CreateElementJoin(IQueryableCollection queryableCollection) { _implied = true; //TODO: always true for now, but not if we later decide to support elements() in the from clause _inElementsFunction = true; IType elementType = queryableCollection.ElementType; if (!elementType.IsEntityType) { throw new InvalidOperationException("Cannot create element join for a collection of non-entities!"); } _queryableCollection = queryableCollection; SessionFactoryHelperExtensions sfh = _fromClause.SessionFactoryHelper; IEntityPersister entityPersister = queryableCollection.ElementPersister; string tableAlias = _fromClause.AliasGenerator.CreateName(entityPersister.EntityName); string associatedEntityName = entityPersister.EntityName; IEntityPersister targetEntityPersister = sfh.RequireClassPersister(associatedEntityName); // Create the FROM element for the target (the elements of the collection). FromElement destination = CreateAndAddFromElement( associatedEntityName, _classAlias, targetEntityPersister, (EntityType)queryableCollection.ElementType, tableAlias ); // If the join is implied, then don't include sub-classes on the element. if (_implied) { destination.IncludeSubclasses = false; } _fromClause.AddCollectionJoinFromElementByPath(_path, destination); // origin.addDestination(destination); // Add the query spaces. _fromClause.Walker.AddQuerySpaces(entityPersister.QuerySpaces); CollectionType type = queryableCollection.CollectionType; string role = type.Role; string roleAlias = _origin.TableAlias; string[] targetColumns = sfh.GetCollectionElementColumns(role, roleAlias); IAssociationType elementAssociationType = sfh.GetElementAssociationType(type); // Create the join element under the from element. JoinSequence joinSequence = sfh.CreateJoinSequence(_implied, elementAssociationType, tableAlias, JoinType.InnerJoin, targetColumns); FromElement elem = InitializeJoin(_path, destination, joinSequence, targetColumns, _origin, false); elem.UseFromFragment = true; // The associated entity is implied, but it must be included in the FROM. elem.CollectionTableAlias = roleAlias; // The collection alias is the role. return elem; }
/// <summary> /// For a collection role, return a list of associations to be fetched by outerjoin /// </summary> private void WalkCollectionTree(IQueryableCollection persister, string alias, string path, int currentDepth) { if (persister.IsOneToMany) { WalkEntityTree((IOuterJoinLoadable)persister.ElementPersister, alias, path, currentDepth); } else { IType type = persister.ElementType; if (type.IsAssociationType) { // a many-to-many // decrement currentDepth here to allow join across the association table // without exceeding MAX_FETCH_DEPTH (i.e. the "currentDepth - 1" bit) IAssociationType associationType = (IAssociationType)type; string[] aliasedLhsColumns = persister.GetElementColumnNames(alias); string[] lhsColumns = persister.ElementColumnNames; // if the current depth is 0, the root thing being loaded is the // many-to-many collection itself. Here, it is alright to use // an inner join... bool useInnerJoin = currentDepth == 0; JoinType joinType = GetJoinType(associationType, persister.FetchMode, path, persister.TableName, lhsColumns, !useInnerJoin, currentDepth - 1, null); AddAssociationToJoinTreeIfNecessary(associationType, aliasedLhsColumns, alias, path, currentDepth - 1, joinType); } else if (type.IsComponentType) { WalkCompositeElementTree((IAbstractComponentType)type, persister.ElementColumnNames, persister, alias, path, currentDepth); } } }
public CollectionPropertyMapping(IQueryableCollection memberPersister) { this.memberPersister = memberPersister; }
public void AddManyToManyJoin(JoinFragment outerjoin, IQueryableCollection collection) { string manyToManyFilter = collection.GetManyToManyFilterFragment(rhsAlias, enabledFilters); SqlString condition = string.Empty.Equals(manyToManyFilter) ? on : StringHelper.IsEmpty(on) ? new SqlString(manyToManyFilter) : on.Append(" and ").Append(manyToManyFilter); outerjoin.AddJoin(joinable.TableName, rhsAlias, lhsColumns, rhsColumns, joinType, condition); outerjoin.AddJoins(joinable.FromJoinFragment(rhsAlias, false, true), joinable.WhereJoinFragment(rhsAlias, false, true)); }
public FromElement CreateCollectionElementsJoin(IQueryableCollection queryableCollection, String collectionName) { JoinSequence collectionJoinSequence = _fromClause.SessionFactoryHelper.CreateCollectionJoinSequence(queryableCollection, collectionName); _queryableCollection = queryableCollection; return CreateCollectionJoin(collectionJoinSequence, null); }
/// <summary> /// For a collection role, return a list of associations to be fetched by outerjoin /// </summary> protected void WalkCollectionTree(IQueryableCollection persister, string alias) { WalkCollectionTree(persister, alias, string.Empty, 0); //TODO: when this is the entry point, we should use an INNER_JOIN for fetching the many-to-many elements! }
public CollectionLoader(IQueryableCollection persister, ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters) : base(factory, enabledFilters) { collectionPersister = persister; }
/// <summary> /// For a composite element, add to a list of associations to be fetched by outerjoin /// </summary> private void WalkCompositeElementTree(IAbstractComponentType compositeType, string[] cols, IQueryableCollection persister, string alias, string path, int currentDepth) { IType[] types = compositeType.Subtypes; string[] propertyNames = compositeType.PropertyNames; int begin = 0; for (int i = 0; i < types.Length; i++) { int length = types[i].GetColumnSpan(factory); string[] lhsColumns = ArrayHelper.Slice(cols, begin, length); if (types[i].IsAssociationType) { IAssociationType associationType = types[i] as IAssociationType; // simple, because we can't have a one-to-one or collection // (or even a property-ref) in a composite element: string[] aliasedLhsColumns = StringHelper.Qualify(alias, lhsColumns); string subpath = SubPath(path, propertyNames[i]); bool[] propertyNullability = compositeType.PropertyNullability; JoinType joinType = GetJoinType(associationType, compositeType.GetFetchMode(i), subpath, persister.TableName, lhsColumns, propertyNullability == null || propertyNullability[i], currentDepth, compositeType.GetCascadeStyle(i)); AddAssociationToJoinTreeIfNecessary(associationType, aliasedLhsColumns, alias, subpath, currentDepth, joinType); } else if (types[i].IsComponentType) { string subpath = SubPath(path, propertyNames[i]); WalkCompositeElementTree((IAbstractComponentType)types[i], lhsColumns, persister, alias, subpath, currentDepth); } begin += length; } }
public OneToManyLoader(IQueryableCollection oneToManyPersister, int batchSize, SqlString subquery, ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters) : base(oneToManyPersister, factory, enabledFilters) { InitializeFromWalker(oneToManyPersister, subquery, batchSize, enabledFilters, factory); }