Skip to content

Commit 2e1ea9c

Browse files
NH-4027 - Missing disposals of enumerators.
1 parent a264f23 commit 2e1ea9c

28 files changed

+410
-399
lines changed

src/NHibernate/AdoNet/Util/BasicFormatter.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,15 @@ static BasicFormatter()
5959

6060
public virtual string Format(string source)
6161
{
62-
return new FormatProcess(source).Perform();
62+
using (var fp = new FormatProcess(source))
63+
return fp.Perform();
6364
}
6465

6566
#endregion
6667

6768
#region Nested type: FormatProcess
6869

69-
private class FormatProcess
70+
private class FormatProcess : IDisposable
7071
{
7172
private readonly List<bool> afterByOrFromOrSelects = new List<bool>();
7273
private readonly List<int> parenCounts = new List<int>();
@@ -441,6 +442,11 @@ private void Newline()
441442
}
442443
beginLine = true;
443444
}
445+
446+
public void Dispose()
447+
{
448+
tokens.Dispose();
449+
}
444450
}
445451

446452
#endregion

src/NHibernate/AdoNet/Util/DdlFormatter.cs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,10 @@ public virtual string Format(string sql)
3838

3939
protected virtual string FormatCommentOn(string sql)
4040
{
41-
StringBuilder result = new StringBuilder(60).Append(Indent1);
42-
IEnumerator<string> tokens = (new StringTokenizer(sql, " '[]\"", true)).GetEnumerator();
43-
44-
bool quoted = false;
45-
while (tokens.MoveNext())
41+
var result = new StringBuilder(60).Append(Indent1);
42+
var quoted = false;
43+
foreach (var token in new StringTokenizer(sql, " '[]\"", true))
4644
{
47-
string token = tokens.Current;
4845
result.Append(token);
4946
if (IsQuote(token))
5047
{
@@ -64,13 +61,10 @@ protected virtual string FormatCommentOn(string sql)
6461

6562
protected virtual string FormatAlterTable(string sql)
6663
{
67-
StringBuilder result = new StringBuilder(60).Append(Indent1);
68-
IEnumerator<string> tokens = (new StringTokenizer(sql, " (,)'[]\"", true)).GetEnumerator();
69-
70-
bool quoted = false;
71-
while (tokens.MoveNext())
64+
var result = new StringBuilder(60).Append(Indent1);
65+
var quoted = false;
66+
foreach (var token in new StringTokenizer(sql, " (,)'[]\"", true))
7267
{
73-
string token = tokens.Current;
7468
if (IsQuote(token))
7569
{
7670
quoted = !quoted;
@@ -90,14 +84,11 @@ protected virtual string FormatAlterTable(string sql)
9084

9185
protected virtual string FormatCreateTable(string sql)
9286
{
93-
StringBuilder result = new StringBuilder(60).Append(Indent1);
94-
IEnumerator<string> tokens = (new StringTokenizer(sql, "(,)'[]\"", true)).GetEnumerator();
95-
96-
int depth = 0;
97-
bool quoted = false;
98-
while (tokens.MoveNext())
87+
var result = new StringBuilder(60).Append(Indent1);
88+
var depth = 0;
89+
var quoted = false;
90+
foreach (var token in new StringTokenizer(sql, "(,)'[]\"", true))
9991
{
100-
string token = tokens.Current;
10192
if (IsQuote(token))
10293
{
10394
quoted = !quoted;

src/NHibernate/Dialect/MsSql2000Dialect.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,13 @@ public override bool SupportsVariableLimit
343343

344344
public override SqlString GetLimitString(SqlString querySqlString, SqlString offset, SqlString limit)
345345
{
346-
var tokenEnum = new SqlTokenizer(querySqlString).GetEnumerator();
347-
if (!tokenEnum.TryParseUntilFirstMsSqlSelectColumn()) return null;
346+
using (var tokenEnum = new SqlTokenizer(querySqlString).GetEnumerator())
347+
{
348+
if (!tokenEnum.TryParseUntilFirstMsSqlSelectColumn()) return null;
348349

349-
int insertPoint = tokenEnum.Current.SqlIndex;
350-
return querySqlString.Insert(insertPoint, new SqlString("top ", limit, " "));
350+
var insertPoint = tokenEnum.Current.SqlIndex;
351+
return querySqlString.Insert(insertPoint, new SqlString("top ", limit, " "));
352+
}
351353
}
352354

353355
/// <summary>

src/NHibernate/Dialect/MsSql2005DialectQueryPager.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ public SqlString PageBy(SqlString offset, SqlString limit)
3333

3434
private SqlString PageByLimitOnly(SqlString limit)
3535
{
36-
var tokenEnum = new SqlTokenizer(_sourceQuery).GetEnumerator();
37-
if (!tokenEnum.TryParseUntilFirstMsSqlSelectColumn()) return null;
38-
39-
int insertPoint = tokenEnum.Current.SqlIndex;
40-
return _sourceQuery.Insert(insertPoint, new SqlString("TOP (", limit, ") "));
36+
using (var tokenEnum = new SqlTokenizer(_sourceQuery).GetEnumerator())
37+
{
38+
if (!tokenEnum.TryParseUntilFirstMsSqlSelectColumn()) return null;
39+
40+
var insertPoint = tokenEnum.Current.SqlIndex;
41+
return _sourceQuery.Insert(insertPoint, new SqlString("TOP (", limit, ") "));
42+
}
4143
}
4244

4345
private SqlString PageByLimitAndOffset(SqlString offset, SqlString limit)

src/NHibernate/Dialect/MsSql2012Dialect.cs

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,31 +58,33 @@ protected override void RegisterFunctions()
5858

5959
public override SqlString GetLimitString(SqlString querySqlString, SqlString offset, SqlString limit)
6060
{
61-
var tokenEnum = new SqlTokenizer(querySqlString).GetEnumerator();
62-
if (!tokenEnum.TryParseUntilFirstMsSqlSelectColumn()) return null;
63-
64-
var result = new SqlStringBuilder(querySqlString);
65-
if (!tokenEnum.TryParseUntil("order"))
61+
using (var tokenEnum = new SqlTokenizer(querySqlString).GetEnumerator())
6662
{
67-
result.Add(" ORDER BY CURRENT_TIMESTAMP");
68-
}
63+
if (!tokenEnum.TryParseUntilFirstMsSqlSelectColumn()) return null;
6964

70-
result.Add(" OFFSET ");
71-
if (offset != null)
72-
{
73-
result.Add(offset).Add(" ROWS");
74-
}
75-
else
76-
{
77-
result.Add("0 ROWS");
78-
}
65+
var result = new SqlStringBuilder(querySqlString);
66+
if (!tokenEnum.TryParseUntil("order"))
67+
{
68+
result.Add(" ORDER BY CURRENT_TIMESTAMP");
69+
}
7970

80-
if (limit != null)
81-
{
82-
result.Add(" FETCH FIRST ").Add(limit).Add(" ROWS ONLY");
83-
}
71+
result.Add(" OFFSET ");
72+
if (offset != null)
73+
{
74+
result.Add(offset).Add(" ROWS");
75+
}
76+
else
77+
{
78+
result.Add("0 ROWS");
79+
}
8480

85-
return result.ToSqlString();
81+
if (limit != null)
82+
{
83+
result.Add(" FETCH FIRST ").Add(limit).Add(" ROWS ONLY");
84+
}
85+
86+
return result.ToSqlString();
87+
}
8688
}
8789
}
8890
}

src/NHibernate/Engine/TypedValue.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,21 @@ private bool IsEquals(IType type, ICollection x, ICollection y)
101101
if (x.Count != y.Count)
102102
return false;
103103

104-
IEnumerator xe = x.GetEnumerator();
105-
IEnumerator ye = y.GetEnumerator();
106-
107-
while (xe.MoveNext())
104+
var ye = y.GetEnumerator();
105+
try
106+
{
107+
foreach (var xItem in x)
108+
{
109+
ye.MoveNext();
110+
if (!type.IsEqual(xItem, ye.Current))
111+
return false;
112+
}
113+
}
114+
finally
108115
{
109-
ye.MoveNext();
110-
if (!type.IsEqual(xe.Current, ye.Current))
111-
return false;
116+
// The old non generic IEnumerator is not disposable, but in most cases the concrete enumerator
117+
// will be a generic one, disposable. https://stackoverflow.com/a/11179175/1178314
118+
(ye as IDisposable)?.Dispose();
112119
}
113120

114121
return true;

src/NHibernate/Event/Default/AbstractFlushingEventListener.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ protected virtual void FlushEverythingToExecutions(FlushEvent @event)
8181
.Append(" removals to ").Append(persistenceContext.CollectionEntries.Count).Append(" collections");
8282

8383
log.Debug(sb.ToString());
84-
new Printer(session.Factory).ToString(persistenceContext.EntitiesByKey.Values.ToArray().GetEnumerator());
84+
new Printer(session.Factory).ToString(persistenceContext.EntitiesByKey.Values.ToArray());
8585
}
8686
}
8787

src/NHibernate/Hql/Ast/ANTLR/Tree/FromClause.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,11 +363,10 @@ public override string ToString()
363363
public virtual void Resolve()
364364
{
365365
// Make sure that all from elements registered with this FROM clause are actually in the AST.
366-
var iter = (new ASTIterator(GetFirstChild())).GetEnumerator();
367366
var childrenInTree = new HashSet<IASTNode>();
368-
while (iter.MoveNext())
367+
foreach (var ast in new ASTIterator(GetFirstChild()))
369368
{
370-
childrenInTree.Add(iter.Current);
369+
childrenInTree.Add(ast);
371370
}
372371
foreach (var fromElement in _fromElements)
373372
{

src/NHibernate/Hql/QuerySplitter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public static string[] ConcreteQueries(string query, ISessionFactoryImplementor
113113
templateQuery.Append(token);
114114
}
115115
string[] results =
116-
StringHelper.Multiply(templateQuery.ToString(), placeholders.GetEnumerator(), replacements.GetEnumerator());
116+
StringHelper.Multiply(templateQuery.ToString(), placeholders, replacements);
117117
if (results.Length == 0)
118118
{
119119
log.Warn("no persistent classes found for query class: " + query);

src/NHibernate/Impl/EnumerableImpl.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ namespace NHibernate.Impl
1515
/// Provides an <see cref="IEnumerable"/> wrapper over the results of an <see cref="IQuery"/>.
1616
/// </summary>
1717
/// <remarks>
18-
/// This is the IteratorImpl in H2.0.3
18+
/// <para>This is the IteratorImpl in H2.0.3</para>
19+
/// <para>This thing is scary. It is an <see cref="IEnumerable" /> which returns itself as a <see cref="IEnumerator" />
20+
/// when <c>GetEnumerator</c> is called, and EnumerableImpl is disposable. Iterating over it with a <c>foreach</c>
21+
/// will cause it to be disposed, probably unexpectedly. (https://stackoverflow.com/a/11179175/1178314)
22+
/// "Fortunately", it does not currently support multiple iterations anyway.</para>
1923
/// </remarks>
2024
public class EnumerableImpl : IEnumerable, IEnumerator, IDisposable
2125
{

0 commit comments

Comments
 (0)