public Join(ISessionFactoryImplementor factory, IAssociationType associationType, string alias, JoinType joinType,
             string[] lhsColumns)
 {
     this.associationType = associationType;
     this.joinable        = associationType.GetAssociatedJoinable(factory);
     this.alias           = alias;
     this.joinType        = joinType;
     this.lhsColumns      = lhsColumns;
     this.rhsColumns      = lhsColumns.Length > 0
                             ? JoinHelper.GetRHSColumnNames(joinable, associationType)
                             : Array.Empty <string>();
 }
        private SqlString GetTableGroupJoinWithClause(SqlString[] withClauseFragments, Join first)
        {
            SqlStringBuilder fromFragment = new SqlStringBuilder();

            fromFragment.Add(")").Add(" on ");

            String[] lhsColumns        = first.LHSColumns;
            var      isAssociationJoin = lhsColumns.Length > 0;

            if (isAssociationJoin)
            {
                String   rhsAlias   = first.Alias;
                String[] rhsColumns = JoinHelper.GetRHSColumnNames(first.AssociationType, factory);
                for (int j = 0; j < lhsColumns.Length; j++)
                {
                    fromFragment.Add(lhsColumns[j]);
                    fromFragment.Add("=");
                    fromFragment.Add(rhsAlias);
                    fromFragment.Add(".");
                    fromFragment.Add(rhsColumns[j]);
                    if (j < lhsColumns.Length - 1)
                    {
                        fromFragment.Add(" and ");
                    }
                }
            }

            for (var i = 0; i < withClauseFragments.Length; i++)
            {
                var withClause = withClauseFragments[i];
                if (SqlStringHelper.IsEmpty(withClause))
                {
                    continue;
                }

                if (withClause.StartsWithCaseInsensitive(" and "))
                {
                    if (!isAssociationJoin)
                    {
                        withClause = withClause.Substring(4);
                    }
                }
                else if (isAssociationJoin)
                {
                    fromFragment.Add(" and ");
                }

                fromFragment.Add(withClause);
            }

            return(fromFragment.ToSqlString());
        }
        private bool ProcessAsTableGroupJoin(bool includeAllSubclassJoins, SqlString[] withClauseFragments, JoinFragment joinFragment)
        {
            if (!NeedsTableGroupJoin(joins, withClauseFragments, includeAllSubclassJoins))
            {
                return(false);
            }

            var    first      = joins[0];
            string joinString = ANSIJoinFragment.GetJoinString(first.JoinType);

            joinFragment.AddFromFragmentString(
                new SqlString(
                    joinString,
                    " (",
                    first.Joinable.TableName,
                    " ",
                    first.Alias
                    ));

            foreach (var join in joins)
            {
                if (join != first)
                {
                    joinFragment.AddJoin(
                        join.Joinable.TableName,
                        join.Alias,
                        join.LHSColumns,
                        JoinHelper.GetRHSColumnNames(join.AssociationType, factory),
                        join.JoinType,
                        SqlString.Empty);
                }

                AddSubclassJoins(
                    joinFragment,
                    join.Alias,
                    join.Joinable,
                    // TODO (from hibernate): Think about if this could be made always true
                    // NH Specific: made always true (original check: join.JoinType == JoinType.InnerJoin)
                    true,
                    includeAllSubclassJoins
                    );
            }

            var tableGroupWithClause = GetTableGroupJoinWithClause(withClauseFragments, first);

            joinFragment.AddFromFragmentString(tableGroupWithClause);
            return(true);
        }
Exemple #4
0
        internal static bool ProcessAsTableGroupJoin(IReadOnlyList <IJoin> tableGroupJoinables, SqlString[] withClauseFragments, bool includeAllSubclassJoins, JoinFragment joinFragment, Func <string, bool> isSubclassIncluded, ISessionFactoryImplementor sessionFactoryImplementor)
        {
            if (!NeedsTableGroupJoin(tableGroupJoinables, withClauseFragments, includeAllSubclassJoins))
            {
                return(false);
            }

            var    first      = tableGroupJoinables[0];
            string joinString = ANSIJoinFragment.GetJoinString(first.JoinType);

            joinFragment.AddFromFragmentString(
                new SqlString(
                    joinString,
                    " (",
                    first.Joinable.TableName,
                    " ",
                    first.Alias
                    ));

            foreach (var join in tableGroupJoinables)
            {
                if (join != first)
                {
                    joinFragment.AddJoin(
                        join.Joinable.TableName,
                        join.Alias,
                        join.LHSColumns,
                        JoinHelper.GetRHSColumnNames(join.AssociationType, sessionFactoryImplementor),
                        join.JoinType,
                        SqlString.Empty);
                }

                bool include = includeAllSubclassJoins && isSubclassIncluded(join.Alias);
                // TODO (from hibernate): Think about if this could be made always true
                // NH Specific: made always true (original check: join.JoinType == JoinType.InnerJoin)
                const bool innerJoin = true;
                joinFragment.AddJoins(
                    join.Joinable.FromJoinFragment(join.Alias, innerJoin, include),
                    join.Joinable.WhereJoinFragment(join.Alias, innerJoin, include));
            }

            var withClause = GetTableGroupJoinWithClause(withClauseFragments, first, sessionFactoryImplementor);

            joinFragment.AddFromFragmentString(withClause);
            return(true);
        }
Exemple #5
0
        private static SqlString GetTableGroupJoinWithClause(SqlString[] withClauseFragments, IJoin first, ISessionFactoryImplementor factory)
        {
            SqlStringBuilder fromFragment = new SqlStringBuilder();

            fromFragment.Add(")").Add(" on ");

            string[] lhsColumns        = first.LHSColumns;
            var      isAssociationJoin = lhsColumns.Length > 0;

            if (isAssociationJoin)
            {
                string   rhsAlias   = first.Alias;
                string[] rhsColumns = JoinHelper.GetRHSColumnNames(first.AssociationType, factory);
                fromFragment.Add(lhsColumns[0]).Add("=").Add(rhsAlias).Add(".").Add(rhsColumns[0]);
                for (int j = 1; j < lhsColumns.Length; j++)
                {
                    fromFragment.Add(" and ").Add(lhsColumns[j]).Add("=").Add(rhsAlias).Add(".").Add(rhsColumns[j]);
                }
            }

            AppendWithClause(fromFragment, isAssociationJoin, withClauseFragments);

            return(fromFragment.ToSqlString());
        }
        internal JoinFragment ToJoinFragment(
            IDictionary <string, IFilter> enabledFilters,
            bool includeExtraJoins,
            SqlString withClauseFragment,
            string withClauseJoinAlias,
            string withRootAlias)
        {
            QueryJoinFragment joinFragment = new QueryJoinFragment(factory.Dialect, useThetaStyle);

            if (rootJoinable != null)
            {
                joinFragment.AddCrossJoin(rootJoinable.TableName, withRootAlias);
                string filterCondition = rootJoinable.FilterFragment(withRootAlias, enabledFilters);
                // JoinProcessor needs to know if the where clause fragment came from a dynamic filter or not so it
                // can put the where clause fragment in the right place in the SQL AST.   'hasFilterCondition' keeps track
                // of that fact.
                joinFragment.HasFilterCondition = joinFragment.AddCondition(filterCondition);
                if (includeExtraJoins)
                {
                    //TODO: not quite sure about the full implications of this!
                    AddExtraJoins(joinFragment, withRootAlias, rootJoinable, true);
                }
            }

            IJoinable last = rootJoinable;

            for (int i = 0; i < joins.Count; i++)
            {
                Join      join      = joins[i];
                string    on        = join.AssociationType.GetOnCondition(join.Alias, factory, enabledFilters);
                SqlString condition = new SqlString();
                if (last != null &&
                    IsManyToManyRoot(last) &&
                    ((IQueryableCollection)last).ElementType == join.AssociationType)
                {
                    // the current join represents the join between a many-to-many association table
                    // and its "target" table.  Here we need to apply any additional filters
                    // defined specifically on the many-to-many
                    string manyToManyFilter = ((IQueryableCollection)last)
                                              .GetManyToManyFilterFragment(join.Alias, enabledFilters);
                    condition = new SqlString("".Equals(manyToManyFilter)
                                                                                                ? on
                                                                                                : "".Equals(on)
                                                                                                                ? manyToManyFilter
                                                                                                                : on + " and " + manyToManyFilter);
                }
                else
                {
                    // NH Different behavior : NH1179 and NH1293
                    // Apply filters in Many-To-One association
                    var enabledForManyToOne = FilterHelper.GetEnabledForManyToOne(enabledFilters);
                    condition = new SqlString(string.IsNullOrEmpty(on) && enabledForManyToOne.Count > 0
                                                        ? join.Joinable.FilterFragment(join.Alias, enabledForManyToOne)
                                                        : on);
                }

                if (withClauseFragment != null)
                {
                    if (join.Alias.Equals(withClauseJoinAlias))
                    {
                        condition = condition.Append(" and ").Append(withClauseFragment);
                    }
                }

                // NH: the variable "condition" have to be a SqlString because it may contains Parameter instances with BackTrack
                joinFragment.AddJoin(
                    join.Joinable.TableName,
                    join.Alias,
                    join.LHSColumns,
                    JoinHelper.GetRHSColumnNames(join.AssociationType, factory),
                    join.JoinType,
                    condition
                    );
                if (includeExtraJoins)
                {
                    //TODO: not quite sure about the full implications of this!
                    AddExtraJoins(joinFragment, join.Alias, join.Joinable, join.JoinType == JoinType.InnerJoin);
                }
                last = join.Joinable;
            }
            if (next != null)
            {
                joinFragment.AddFragment(next.ToJoinFragment(enabledFilters, includeExtraJoins));
            }
            joinFragment.AddCondition(conditions.ToSqlString());
            if (isFromPart)
            {
                joinFragment.ClearWherePart();
            }
            return(joinFragment);
        }
        internal JoinFragment ToJoinFragment(
            IDictionary <string, IFilter> enabledFilters,
            bool includeAllSubclassJoins,
            bool renderSubclassJoins,
            SqlString withClauseFragment)
        {
            QueryJoinFragment joinFragment = new QueryJoinFragment(factory.Dialect, useThetaStyle);

            if (rootJoinable != null)
            {
                joinFragment.AddCrossJoin(rootJoinable.TableName, rootAlias);
                string filterCondition = rootJoinable.FilterFragment(rootAlias, enabledFilters);
                // JoinProcessor needs to know if the where clause fragment came from a dynamic filter or not so it
                // can put the where clause fragment in the right place in the SQL AST.   'hasFilterCondition' keeps track
                // of that fact.
                joinFragment.HasFilterCondition = joinFragment.AddCondition(filterCondition);
                AddSubclassJoins(joinFragment, rootAlias, rootJoinable, true, includeAllSubclassJoins);
            }

            var       withClauses = new SqlString[joins.Count];
            IJoinable last        = rootJoinable;

            for (int i = 0; i < joins.Count; i++)
            {
                Join join = joins[i];

                withClauses[i] = GetWithClause(enabledFilters, ref withClauseFragment, join, last);
                last           = join.Joinable;
            }

            if (rootJoinable == null && ProcessAsTableGroupJoin(includeAllSubclassJoins, withClauses, joinFragment))
            {
                return(joinFragment);
            }

            for (int i = 0; i < joins.Count; i++)
            {
                Join join = joins[i];

                // NH: the variable "condition" have to be a SqlString because it may contains Parameter instances with BackTrack
                joinFragment.AddJoin(
                    join.Joinable.TableName,
                    join.Alias,
                    join.LHSColumns,
                    JoinHelper.GetRHSColumnNames(join.AssociationType, factory),
                    join.JoinType,
                    withClauses[i]
                    );

                AddSubclassJoins(joinFragment, join.Alias, join.Joinable, join.JoinType == JoinType.InnerJoin, renderSubclassJoins);
            }

            if (next != null)
            {
                joinFragment.AddFragment(next.ToJoinFragment(enabledFilters, includeAllSubclassJoins));
            }
            joinFragment.AddCondition(conditions.ToSqlString());
            if (isFromPart)
            {
                joinFragment.ClearWherePart();
            }
            return(joinFragment);
        }