Skip to content

Commit ad206cf

Browse files
committed
NH-3480 - Code reorganization and cleanup
1 parent 07f306d commit ad206cf

File tree

5 files changed

+87
-58
lines changed

5 files changed

+87
-58
lines changed

src/NHibernate/Loader/Collection/OneToManyJoinWalker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ private void InitStatementString(IOuterJoinLoadable elementPersister, string ali
5858
int collectionJoins = CountCollectionPersisters(associations) + 1;
5959
CollectionSuffixes = BasicLoader.GenerateSuffixes(joins + 1, collectionJoins);
6060

61-
SqlStringBuilder whereString = WhereString(oneToManyPersister.CollectionType.UseLHSPrimaryKey ? alias : alias + "owner_", oneToManyPersister.KeyColumnNames, subquery, batchSize);
61+
SqlStringBuilder whereString = WhereString(oneToManyPersister.GenerateTableAliasForKeyColumns(alias), oneToManyPersister.KeyColumnNames, subquery, batchSize);
6262
string filter = oneToManyPersister.FilterFragment(alias, EnabledFilters);
6363
whereString.Insert(0, StringHelper.MoveAndToBeginning(filter));
6464

src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ public AbstractCollectionPersister(Mapping.Collection collection, ICacheConcurre
254254
foreach (Column col in collection.Owner.Key.ColumnIterator)
255255
{
256256
keyColumnNames[k] = col.GetQuotedName(dialect);
257-
keyColumnAliases[k] = col.GetAlias(dialect) + "_owner_";
257+
keyColumnAliases[k] = col.GetAlias(dialect) + "_owner_"; // Force the alias to be unique in case it conflicts with an alias in the entity
258258
k++;
259259
}
260260
joinColumnNames = new string[collection.Key.ColumnSpan];
@@ -1987,6 +1987,11 @@ protected Dialect.Dialect Dialect
19871987
public abstract bool CascadeDeleteEnabled { get; }
19881988
public abstract bool IsOneToMany { get; }
19891989

1990+
public virtual string GenerateTableAliasForKeyColumns(string alias)
1991+
{
1992+
return alias;
1993+
}
1994+
19901995
protected object PerformInsert(object ownerId, IPersistentCollection collection, IExpectation expectation,
19911996
object entry, int index, bool useBatch, bool callable, ISessionImplementor session)
19921997
{

src/NHibernate/Persister/Collection/IQueryableCollection.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,12 @@ public interface IQueryableCollection : IPropertyMapping, IJoinable, ICollection
8080
/// <param name="alias">The alias for the many-to-many target table</param>
8181
/// <returns>Appropriate order-by fragment or empty string.</returns>
8282
string GetManyToManyOrderByString(string alias);
83+
84+
/// <summary>
85+
/// Generate the table alias to use for the collection's key columns
86+
/// </summary>
87+
/// <param name="alias">The alias for thetarget table</param>
88+
/// <returns>Appropriate table alias.</returns>
89+
string GenerateTableAliasForKeyColumns(string alias);
8390
}
8491
}

src/NHibernate/Persister/Collection/OneToManyPersister.cs

Lines changed: 23 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -64,69 +64,31 @@ public override bool IsManyToMany
6464
/// <returns></returns>
6565
protected override SqlCommandInfo GenerateDeleteString()
6666
{
67+
var update = new SqlUpdateBuilder(Factory.Dialect, Factory)
68+
.SetTableName(qualifiedTableName)
69+
.AddColumns(JoinColumnNames, "null");
70+
6771
if (CollectionType.UseLHSPrimaryKey)
6872
{
69-
var update = new SqlUpdateBuilder(Factory.Dialect, Factory)
70-
.SetTableName(qualifiedTableName)
71-
.AddColumns(KeyColumnNames, "null")
72-
.SetIdentityColumn(KeyColumnNames, KeyType);
73-
74-
if (HasIndex)
75-
update.AddColumns(IndexColumnNames, "null");
76-
77-
if (HasWhere)
78-
update.AddWhereFragment(sqlWhereString);
79-
80-
if (Factory.Settings.IsCommentsEnabled)
81-
update.SetComment("delete one-to-many " + Role);
82-
83-
return update.ToSqlCommandInfo();
73+
update.SetIdentityColumn(KeyColumnNames, KeyType);
8474
}
8575
else
8676
{
87-
var deleteSql = new SqlStringBuilder();
77+
var ownerPersister = (IOuterJoinLoadable)OwnerEntityPersister;
78+
update.SetJoin(ownerPersister.TableName, JoinColumnNames, ownerPersister.GetPropertyColumnNames(CollectionType.LHSPropertyName));
79+
update.SetIdentityColumn(ownerPersister.TableName, KeyColumnNames, KeyType);
80+
}
8881

89-
deleteSql.Add("update " + qualifiedTableName + " set ");
90-
bool andNeeded = false;
91-
foreach (string nextColumn in JoinColumnNames)
92-
{
93-
if (andNeeded)
94-
{
95-
deleteSql.Add(" and ");
96-
}
97-
deleteSql.Add(nextColumn + " = null");
98-
andNeeded = true;
99-
}
82+
if (HasIndex)
83+
update.AddColumns(IndexColumnNames, "null");
10084

101-
var ownerPersister = (IOuterJoinLoadable)OwnerEntityPersister;
102-
deleteSql.Add(" from " + qualifiedTableName + " inner join " + ownerPersister.TableName + " on ");
103-
var ownerJoinColumns = ownerPersister.GetPropertyColumnNames(CollectionType.LHSPropertyName);
104-
andNeeded = false;
105-
for (int columnIndex = 0; columnIndex < JoinColumnNames.Length; columnIndex++)
106-
{
107-
if (andNeeded)
108-
{
109-
deleteSql.Add(" and ");
110-
}
111-
deleteSql.Add(qualifiedTableName + StringHelper.Dot + JoinColumnNames[columnIndex] + " = " + ownerPersister.TableName + StringHelper.Dot + ownerJoinColumns[columnIndex]);
112-
andNeeded = true;
113-
}
85+
if (HasWhere)
86+
update.AddWhereFragment(sqlWhereString);
11487

115-
deleteSql.Add(" where ");
116-
andNeeded = false;
117-
foreach (string nextColumn in KeyColumnNames)
118-
{
119-
if (andNeeded)
120-
{
121-
deleteSql.Add(" and ");
122-
}
123-
deleteSql.Add(ownerPersister.TableName + StringHelper.Dot + nextColumn + " = ");
124-
deleteSql.AddParameter();
125-
andNeeded = true;
126-
}
88+
if (Factory.Settings.IsCommentsEnabled)
89+
update.SetComment("delete one-to-many " + Role);
12790

128-
return new SqlCommandInfo(deleteSql.ToSqlString(), KeyType.SqlTypes(Factory));
129-
}
91+
return update.ToSqlCommandInfo();
13092
}
13193

13294
/// <summary>
@@ -198,6 +160,11 @@ public override bool ConsumesCollectionAlias()
198160
return true;
199161
}
200162

163+
public override string GenerateTableAliasForKeyColumns(string alias)
164+
{
165+
return CollectionType.UseLHSPrimaryKey ? alias : alias + "owner_";
166+
}
167+
201168
protected override int DoUpdateRows(object id, IPersistentCollection collection, ISessionImplementor session)
202169
{
203170
// we finish all the "removes" first to take care of possible unique
@@ -368,7 +335,7 @@ protected override SelectFragment GenerateSelectFragment(string alias, string co
368335
for (int i = 0; i < columnNames.Length; i++)
369336
{
370337
var column = columnNames[i];
371-
var tableAlias = ojl.GenerateTableAliasForColumn(alias + (CollectionType.UseLHSPrimaryKey ? String.Empty : "owner_"), column);
338+
var tableAlias = CollectionType.UseLHSPrimaryKey ? ojl.GenerateTableAliasForColumn(alias, column) : GenerateTableAliasForKeyColumns(alias);
372339
selectFragment.AddColumn(tableAlias, column, columnAliases[i]);
373340
}
374341
return selectFragment;
@@ -402,7 +369,7 @@ public override SqlString FromJoinFragment(string alias, bool innerJoin, bool in
402369
}
403370

404371
var ownerPersister = (IOuterJoinLoadable)OwnerEntityPersister;
405-
join.AddJoin(ownerPersister.TableName, alias + "owner_", lhsKeyColumnNames, ownerPersister.GetPropertyColumnNames(CollectionType.LHSPropertyName), JoinType.LeftOuterJoin);
372+
join.AddJoin(ownerPersister.TableName, GenerateTableAliasForKeyColumns(alias), lhsKeyColumnNames, ownerPersister.GetPropertyColumnNames(CollectionType.LHSPropertyName), innerJoin ? JoinType.InnerJoin : JoinType.LeftOuterJoin);
406373
return join.ToFromFragmentString + elementJoinFragment;
407374
}
408375

src/NHibernate/SqlCommand/SqlUpdateBuilder.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class SqlUpdateBuilder : SqlBaseBuilder, ISqlStringBuilder
2020
// columns-> (ColumnName, Value) or (ColumnName, SqlType) for parametrized column
2121
private readonly LinkedHashMap<string, object> columns = new LinkedHashMap<string, object>();
2222

23+
private SqlString join = null;
24+
2325
private List<SqlString> whereStrings = new List<SqlString>();
2426
private readonly List<SqlType> whereParameterTypes = new List<SqlType>();
2527
private SqlString assignments;
@@ -128,6 +130,28 @@ public SqlUpdateBuilder AppendAssignmentFragment(SqlString fragment)
128130
return this;
129131
}
130132

133+
public SqlUpdateBuilder SetJoin(string joinTableName, string[] lhsColumnNames, string[] rhsColumnNames)
134+
{
135+
SqlStringBuilder joinStringBuilder = new SqlStringBuilder();
136+
137+
joinStringBuilder.Add(" INNER JOIN ");
138+
joinStringBuilder.Add(joinTableName);
139+
joinStringBuilder.Add(" ON ");
140+
bool andNeeded = false;
141+
for (int columnIndex = 0; columnIndex < lhsColumnNames.Length; columnIndex++)
142+
{
143+
if (andNeeded)
144+
{
145+
joinStringBuilder.Add(" AND ");
146+
}
147+
joinStringBuilder.Add(tableName + StringHelper.Dot + lhsColumnNames[columnIndex] + " = " + joinTableName + StringHelper.Dot + rhsColumnNames[columnIndex]);
148+
andNeeded = true;
149+
}
150+
151+
join = joinStringBuilder.ToSqlString();
152+
return this;
153+
}
154+
131155
public SqlUpdateBuilder SetWhere(string whereSql)
132156
{
133157
if (StringHelper.IsNotEmpty(whereSql))
@@ -150,6 +174,20 @@ public SqlUpdateBuilder SetIdentityColumn(string[] columnNames, IType identityTy
150174
return this;
151175
}
152176

177+
/// <summary>
178+
/// Sets the IdentityColumn for the <c>UPDATE</c> sql to use.
179+
/// </summary>
180+
/// <param name="tableName">Table name to prepend to the columns.</param>
181+
/// <param name="columnNames">An array of the column names for the Property</param>
182+
/// <param name="identityType">The IType of the Identity Property.</param>
183+
/// <returns>The SqlUpdateBuilder.</returns>
184+
public SqlUpdateBuilder SetIdentityColumn(string tableName, string[] columnNames, IType identityType)
185+
{
186+
whereStrings.Add(ToWhereString(tableName, columnNames));
187+
whereParameterTypes.AddRange(identityType.SqlTypes(Mapping));
188+
return this;
189+
}
190+
153191
/// <summary>
154192
/// Sets the VersionColumn for the <c>UPDATE</c> sql to use.
155193
/// </summary>
@@ -232,6 +270,11 @@ public SqlString ToSqlString()
232270
{
233271
initialCapacity += (columns.Count - 1) + (columns.Count * 3);
234272
}
273+
274+
// 3 - JOIN
275+
if (join != null)
276+
initialCapacity += 3;
277+
235278
// 1 = "WHERE"
236279
initialCapacity++;
237280

@@ -282,6 +325,13 @@ public SqlString ToSqlString()
282325
sqlBuilder.Add(assignments);
283326
}
284327

328+
if (join != null)
329+
{
330+
sqlBuilder.Add(" FROM ");
331+
sqlBuilder.Add(tableName);
332+
sqlBuilder.Add(join);
333+
}
334+
285335
sqlBuilder.Add(" WHERE ");
286336
bool andNeeded = false;
287337
foreach (SqlString whereString in whereStrings)

0 commit comments

Comments
 (0)