|
From: <aye...@us...> - 2008-07-18 07:32:52
|
Revision: 3640
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3640&view=rev
Author: ayenderahien
Date: 2008-07-18 07:32:56 +0000 (Fri, 18 Jul 2008)
Log Message:
-----------
NH-1359 - Applying patch from Will Shaver to create an IProjection from a DetachedCriteria
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs
trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs
trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs
trunk/nhibernate/src/NHibernate/Loader/Loader.cs
trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj
trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj
trunk/nhibernate/src/NHibernate/SqlCommand/InFragment.cs
trunk/nhibernate/src/NHibernate/SqlCommand/SubselectClauseExtractor.cs
trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1101/Domain.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/SelectSubqueryExpression.cs
trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Person.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -241,5 +241,11 @@
{
return new ConditionalProjection(criterion, whenTrue, whenFalse);
}
+
+ public static IProjection SubQuery(DetachedCriteria detachedCriteria)
+ {
+ SelectSubqueryExpression expr = new SelectSubqueryExpression(detachedCriteria);
+ return new SubqueryProjection(expr);
+ }
}
-}
\ No newline at end of file
+}
Added: trunk/nhibernate/src/NHibernate/Criterion/SelectSubqueryExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/SelectSubqueryExpression.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/SelectSubqueryExpression.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -0,0 +1,23 @@
+using System;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion
+{
+ /// <summary>
+ /// A comparison between a property value in the outer query and the
+ /// result of a subquery
+ /// </summary>
+ [Serializable]
+ public class SelectSubqueryExpression : SubqueryExpression
+ {
+ internal SelectSubqueryExpression(DetachedCriteria dc)
+ : base(null, null, dc)
+ {
+ }
+
+ protected override SqlString ToLeftSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery)
+ {
+ return SqlString.Empty;
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -190,5 +190,10 @@
{
return new SimpleSubqueryExpression(value, "<=", "some", dc);
}
+
+ public static AbstractCriterion Select(DetachedCriteria detachedCriteria)
+ {
+ return new SelectSubqueryExpression(detachedCriteria);
+ }
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -27,7 +27,7 @@
this.op = op;
}
- protected IType[] GetTypes()
+ public IType[] GetTypes()
{
return types;
}
@@ -98,7 +98,7 @@
return null;
}
- private void InitializeInnerQueryAndParameters(ICriteriaQuery criteriaQuery)
+ public void InitializeInnerQueryAndParameters(ICriteriaQuery criteriaQuery)
{
ISessionFactoryImplementor factory = criteriaQuery.Factory;
innerQuery =
@@ -115,4 +115,4 @@
get { return criteriaImpl; }
}
}
-}
\ No newline at end of file
+}
Added: trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -0,0 +1,59 @@
+using System;
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+using NHibernate.Type;
+
+namespace NHibernate.Criterion
+{
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// A property value, or grouped property value
+ /// </summary>
+ [Serializable]
+ public class SubqueryProjection : SimpleProjection
+ {
+ private SelectSubqueryExpression _subQuery;
+
+ protected internal SubqueryProjection(SelectSubqueryExpression subquery)
+ {
+ _subQuery = subquery;
+ }
+ public override string ToString()
+ {
+ return _subQuery.ToString();
+ }
+
+ public override bool IsGrouped
+ {
+ get { return false; }
+ }
+
+ public override bool IsAggregate
+ {
+ get { return false; }
+ }
+
+ public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
+ {
+ _subQuery.InitializeInnerQueryAndParameters(criteriaQuery);
+ return _subQuery.GetTypes();
+ }
+
+ public override SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
+ {
+ SqlString sqlStringSubquery = _subQuery.ToSqlString(criteria, criteriaQuery, enabledFilters);
+ return sqlStringSubquery.Append(new SqlString(new object[]
+ {
+ " as y",
+ loc.ToString(),
+ "_"
+ }));
+ }
+
+ public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
+ {
+ throw new InvalidOperationException("not a grouping projection");
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -73,7 +73,7 @@
.Add(StringHelper.Join(", ", columnsOrAliases))
.Add(" FROM (SELECT ROW_NUMBER() OVER(ORDER BY ");
- AppendSortExpressions(sortExpressions, result);
+ AppendSortExpressions(columnsOrAliases, sortExpressions, result);
result.Add(") as row, ");
@@ -84,22 +84,27 @@
if (notLastColumn)
result.Add(", ");
}
-
- for (int i = 1; i <= sortExpressions.Length; ++i)
+ for (int i = 0; i < sortExpressions.Length; i++)
{
- result.Add(", query.__hibernate_sort_expr_")
- .Add(i.ToString())
- .Add("__");
+ string sortExpression = RemoveSortOrderDirection(sortExpressions[i]);
+ if(!columnsOrAliases.Contains(sortExpression))
+ {
+ result.Add(", query.__hibernate_sort_expr_")
+ .Add(i.ToString())
+ .Add("__");
+ }
}
result.Add(" FROM (")
.Add(select);
- for (int i = 1; i <= sortExpressions.Length; i++)
+ for (int i = 0; i < sortExpressions.Length; i++)
{
- // Drop the ASC/DESC at the end of the sort expression which might look like "count(distinct frog.Id)desc" or "frog.Name asc".
- string sortExpression = Regex.Replace(sortExpressions[i - 1].Trim(), @"(\)|\s)(?i:asc|desc)$", "$1").Trim();
+ string sortExpression = RemoveSortOrderDirection(sortExpressions[i]);
+ if(columnsOrAliases.Contains(sortExpression))
+ continue;
+
if (aliasToColumn.ContainsKey(sortExpression))
sortExpression = aliasToColumn[sortExpression];
@@ -116,23 +121,36 @@
.Add(offset.ToString())
.Add(" ORDER BY ");
- AppendSortExpressions(sortExpressions, result);
+ AppendSortExpressions(columnsOrAliases, sortExpressions, result);
return result.ToSqlString();
}
- private void AppendSortExpressions(string[] sortExpressions, SqlStringBuilder result)
+ private static string RemoveSortOrderDirection(string sortExpression)
{
- for (int i = 1; i <= sortExpressions.Length; i++)
+ // Drop the ASC/DESC at the end of the sort expression which might look like "count(distinct frog.Id)desc" or "frog.Name asc".
+ return Regex.Replace(sortExpression.Trim(), @"(\)|\s)(?i:asc|desc)$", "$1").Trim();
+ }
+
+ private static void AppendSortExpressions(ICollection<string> columnsOrAliases, string[] sortExpressions, SqlStringBuilder result)
+ {
+ for (int i = 0; i < sortExpressions.Length; i++)
{
- if (i > 1)
+ if(i > 1)
result.Add(", ");
- result.Add("__hibernate_sort_expr_")
- .Add(i.ToString())
- .Add("__");
-
- if (sortExpressions[i - 1].Trim().ToLower().EndsWith("desc"))
+ string sortExpression = RemoveSortOrderDirection(sortExpressions[i]);
+ if(columnsOrAliases.Contains(sortExpression))
+ {
+ result.Add(sortExpression);
+ }
+ else
+ {
+ result.Add("__hibernate_sort_expr_")
+ .Add(i.ToString())
+ .Add("__");
+ }
+ if (sortExpressions[i].Trim().ToLower().EndsWith("desc"))
result.Add(" DESC");
}
}
@@ -181,6 +199,8 @@
index += 1;
}
+ string alias = token;
+
bool isFunctionCallOrQuotedString = token.Contains("'") || token.Contains("(");
// this is heuristic guess, if the expression contains ' or (, it is probably
// not appropriate to just slice parts off of it
@@ -188,11 +208,9 @@
{
int dot = token.IndexOf('.');
if (dot != -1)
- token = token.Substring(dot + 1);
+ alias = token.Substring(dot + 1);
}
- string alias = token;
-
// notice! we are checking here the existence of "as" "alias", two
// tokens from the current one
if (index + 1 < tokens.Count &&
Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -391,7 +391,7 @@
int entitySpan = EntityPersisters.Length;
ArrayList hydratedObjects = entitySpan == 0 ? null : new ArrayList(entitySpan * 10);
- ;
+
IDbCommand st = PrepareQueryCommand(queryParameters, false, session);
IDataReader rs =
@@ -1830,4 +1830,4 @@
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj 2008-07-18 07:32:56 UTC (rev 3640)
@@ -586,6 +586,7 @@
<Compile Include="Dialect\Lock\UpdateLockingStrategy.cs" />
<Compile Include="Dialect\MsSqlCeDialect.cs" />
<Compile Include="Dialect\MySQL5Dialect.cs" />
+ <Compile Include="Criterion\SelectSubqueryExpression.cs" />
<Compile Include="Dialect\PostgreSQL82Dialect.cs" />
<Compile Include="Dialect\Schema\FirebirdMetaData.cs" />
<Compile Include="Dialect\Schema\ITableMetadata.cs" />
@@ -594,6 +595,7 @@
<Compile Include="Dialect\Sybase11Dialect.cs" />
<Compile Include="Driver\ISqlParameterFormatter.cs" />
<Compile Include="Driver\SqlStringFormatter.cs" />
+ <Compile Include="Criterion\SubqueryProjection.cs" />
<Compile Include="EmptyInterceptor.cs" />
<Compile Include="Engine\ActionQueue.cs" />
<Compile Include="Engine\AssociationKey.cs" />
Modified: trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj 2008-07-18 07:32:56 UTC (rev 3640)
@@ -586,6 +586,7 @@
<Compile Include="Criterion\Restrictions.cs" />
<Compile Include="Criterion\RowCountInt64Projection.cs" />
<Compile Include="Criterion\RowCountProjection.cs" />
+ <Compile Include="Criterion\SelectSubqueryExpression.cs" />
<Compile Include="Criterion\SimpleExpression.cs" />
<Compile Include="Criterion\SimpleProjection.cs" />
<Compile Include="Criterion\SimpleSubqueryExpression.cs" />
@@ -594,6 +595,7 @@
<Compile Include="Criterion\SQLProjection.cs" />
<Compile Include="Criterion\Subqueries.cs" />
<Compile Include="Criterion\SubqueryExpression.cs" />
+ <Compile Include="Criterion\SubqueryProjection.cs" />
<Compile Include="DebugHelpers\DictionaryProxy.cs" />
<Compile Include="DebugHelpers\CollectionProxy.cs" />
<Compile Include="Dialect\Function\AnsiExtractFunction.cs" />
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/InFragment.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/InFragment.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/InFragment.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -1,3 +1,4 @@
+
using System;
using System.Collections;
using NHibernate.Util;
@@ -119,6 +120,8 @@
}
else
{
+ if(values.Count == 0)
+ throw new ArgumentOutOfRangeException("Attempting to parse a null value into an sql string.");
object value = values[0];
if (Null.Equals(value))
{
@@ -136,4 +139,4 @@
return buf.ToSqlString();
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SubselectClauseExtractor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/SubselectClauseExtractor.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/SubselectClauseExtractor.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -16,7 +16,7 @@
private int lastOrderByIndex;
private int lastOrderByPartIndex;
-
+ private int parenNestCount;
private object[] sqlParts;
/// <summary>
@@ -72,7 +72,7 @@
public SqlString GetSqlString()
{
IEnumerator partEnumerator = sqlParts.GetEnumerator();
-
+ parenNestCount = 0;
// Process the parts until FROM is found
while (partEnumerator.MoveNext())
{
@@ -94,12 +94,11 @@
return builder.ToSqlString();
}
- private static int FindFromClauseInPart(string part)
+ private int FindFromClauseInPart(string part)
{
int afterLastClosingParenIndex = 0;
int fromIndex = StringHelper.IndexOfCaseInsensitive(part, FromClauseToken);
- int parenNestCount = 0;
-
+
for (int i = 0; i < part.Length; i++)
{
if (parenNestCount == 0 && i > fromIndex)
@@ -129,6 +128,9 @@
fromIndex = StringHelper.IndexOfCaseInsensitive(part, FromClauseToken);
}
+ if(parenNestCount > 0)
+ return -1;
+
return fromIndex;
}
Modified: trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -17,49 +17,49 @@
SqlString str = d.GetLimitString(new SqlString("SELECT fish.id FROM fish"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 id FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.id, query.__hibernate_sort_expr_1__ FROM (SELECT fish.id, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 id FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.id, query.__hibernate_sort_expr_0__ FROM (SELECT fish.id, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id FROM fish fish_"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 id FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.id, query.__hibernate_sort_expr_1__ FROM (SELECT DISTINCT fish_.id, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish fish_) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 id FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.id, query.__hibernate_sort_expr_0__ FROM (SELECT DISTINCT fish_.id, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish fish_) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id as ixx9_ FROM fish fish_"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 ixx9_ FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.ixx9_, query.__hibernate_sort_expr_1__ FROM (SELECT DISTINCT fish_.id as ixx9_, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish fish_) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 ixx9_ FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.ixx9_, query.__hibernate_sort_expr_0__ FROM (SELECT DISTINCT fish_.id as ixx9_, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish fish_) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT * FROM fish ORDER BY name"), 5, 15);
Assert.AreEqual(
- "SELECT TOP 15 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.*, query.__hibernate_sort_expr_1__ FROM (SELECT *, name as __hibernate_sort_expr_1__ FROM fish) query ) page WHERE page.row > 5 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 15 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.*, query.__hibernate_sort_expr_0__ FROM (SELECT *, name as __hibernate_sort_expr_0__ FROM fish) query ) page WHERE page.row > 5 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT fish.id, fish.name FROM fish ORDER BY name DESC"), 7, 28);
Assert.AreEqual(
- "SELECT TOP 28 id, name FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__ DESC) as row, query.id, query.name, query.__hibernate_sort_expr_1__ FROM (SELECT fish.id, fish.name, name as __hibernate_sort_expr_1__ FROM fish) query ) page WHERE page.row > 7 ORDER BY __hibernate_sort_expr_1__ DESC",
+ "SELECT TOP 28 id, name FROM (SELECT ROW_NUMBER() OVER(ORDER BY name DESC) as row, query.id, query.name FROM (SELECT fish.id, fish.name FROM fish) query ) page WHERE page.row > 7 ORDER BY name DESC",
str.ToString());
str =
d.GetLimitString(
new SqlString("SELECT * FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t ORDER BY name DESC"), 10, 20);
Assert.AreEqual(
- "SELECT TOP 20 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__ DESC) as row, query.*, query.__hibernate_sort_expr_1__ FROM (SELECT *, name as __hibernate_sort_expr_1__ FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t) query ) page WHERE page.row > 10 ORDER BY __hibernate_sort_expr_1__ DESC",
+ "SELECT TOP 20 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__ DESC) as row, query.*, query.__hibernate_sort_expr_0__ FROM (SELECT *, name as __hibernate_sort_expr_0__ FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t) query ) page WHERE page.row > 10 ORDER BY __hibernate_sort_expr_0__ DESC",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count FROM fish"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 *, some_count FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.*, query.some_count, query.__hibernate_sort_expr_1__ FROM (SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 *, some_count FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.*, query.some_count, query.__hibernate_sort_expr_0__ FROM (SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT * FROM fish WHERE scales = ", Parameter.Placeholder), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.*, query.__hibernate_sort_expr_1__ FROM (SELECT *, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish WHERE scales = ?) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.*, query.__hibernate_sort_expr_0__ FROM (SELECT *, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish WHERE scales = ?) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT f.Type, COUNT(DISTINCT f.Name) AS Name FROM Fish f GROUP BY f.Type ORDER BY COUNT(DISTINCT f.Name)"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 Type, Name FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.Type, query.Name, query.__hibernate_sort_expr_1__ FROM (SELECT f.Type, COUNT(DISTINCT f.Name) AS Name, COUNT(DISTINCT f.Name) as __hibernate_sort_expr_1__ FROM Fish f GROUP BY f.Type) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 Type, Name FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.Type, query.Name, query.__hibernate_sort_expr_0__ FROM (SELECT f.Type, COUNT(DISTINCT f.Name) AS Name, COUNT(DISTINCT f.Name) as __hibernate_sort_expr_0__ FROM Fish f GROUP BY f.Type) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
}
@@ -69,13 +69,13 @@
MsSql2005Dialect d = new MsSql2005Dialect();
SqlString result =
d.GetLimitString(new SqlString("select concat(a.Description,', ', a.Description) as desc from Animal a"), 0, 10);
- Assert.AreEqual("SELECT TOP 10 desc FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.desc, query.__hibernate_sort_expr_1__ FROM (select concat(a.Description,', ', a.Description) as desc, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ from Animal a) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__", result.ToString());
+ Assert.AreEqual("SELECT TOP 10 desc FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.desc, query.__hibernate_sort_expr_0__ FROM (select concat(a.Description,', ', a.Description) as desc, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ from Animal a) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__", result.ToString());
// The test use the function "cast" because cast need the keyWork "as" too
SqlString str =
d.GetLimitString(new SqlString("SELECT fish.id, cast('astring, with,comma' as string) as bar FROM fish"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 id, bar FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.id, query.bar, query.__hibernate_sort_expr_1__ FROM (SELECT fish.id, cast('astring, with,comma' as string) as bar, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 id, bar FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.id, query.bar, query.__hibernate_sort_expr_0__ FROM (SELECT fish.id, cast('astring, with,comma' as string) as bar, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
}
[Test]
Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1101/Domain.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1101/Domain.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1101/Domain.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -2,7 +2,9 @@
{
public class A
{
+#pragma warning disable 649
private int id;
+#pragma warning restore 649
private string descript;
private B b;
public A() {}
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Fixture.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -0,0 +1,196 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using NHibernate.Criterion;
+using NHibernate.Transform;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH1359
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ public override string BugNumber
+ {
+ get { return "NH1359"; }
+ }
+
+ protected override void OnTearDown()
+ {
+ base.OnTearDown();
+ using(ISession session = OpenSession())
+ {
+ using(ITransaction tx = session.BeginTransaction())
+ {
+ session.Delete("from Person");
+ tx.Commit();
+ }
+ }
+ }
+
+ protected override void OnSetUp()
+ {
+ using(ISession s = OpenSession())
+ {
+ using(ITransaction tx = s.BeginTransaction())
+ {
+ Person e1 = new Person("Joe", 10, 9);
+ Person e2 = new Person("Sally", 20, 8);
+ Person e3 = new Person("Tim", 20, 7); //20
+ Person e4 = new Person("Fred", 40, 40);
+ Person e5 = new Person("Fred", 50, 50);
+ s.Save(e1);
+ s.Save(e2);
+ s.Save(e3);
+ s.Save(e4);
+ s.Save(e5);
+ Pet p = new Pet("Fido", "Dog", 25, e1);
+ Pet p2 = new Pet("Biff", "Dog", 10, e1);
+ s.Save(p);
+ s.Save(p2);
+ tx.Commit();
+ }
+ }
+ }
+
+ [Test]
+ public void CanSetSubQueryProjectionFromDetachedCriteriaWithCountProjection()
+ {
+ using(ISession s = OpenSession())
+ {
+ // This query doesn't make sense at all
+ DetachedCriteria dc = DetachedCriteria.For<Person>()
+ .SetProjection(Projections.Count("Id"));
+
+ ICriteria c = s.CreateCriteria(typeof(Person))
+ .SetProjection(Projections.SubQuery(dc))
+ .Add(Expression.Eq("Name", "Fred"));
+
+ IList list = c.List();
+ Assert.AreEqual(2, list.Count);
+ foreach(object item in list)
+ {
+ Assert.AreEqual(5, item);
+ }
+ }
+ }
+
+ public class HeaviestPet
+ {
+ public string Name;
+ public double Weight;
+ }
+
+ [Test]
+ public void CanSubqueryRelatedObjectsNotInMainQuery()
+ {
+ using(ISession s = OpenSession())
+ {
+ DetachedCriteria dc = DetachedCriteria.For<Person>().CreateCriteria("Pets", "pets")
+ .SetProjection(Projections.Max("pets.Weight"));
+ ICriteria c = s.CreateCriteria(typeof(Person))
+ .SetProjection(Projections.ProjectionList()
+ .Add(Projections.SubQuery(dc), "Weight")
+ .Add(Projections.Property("Name"), "Name"))
+ .Add(Restrictions.Eq("Name", "Joe"));
+ c.SetResultTransformer(Transformers.AliasToBean(typeof(HeaviestPet)));
+
+ IList<HeaviestPet> list = c.List<HeaviestPet>();
+ Assert.AreEqual(1, list.Count);
+ foreach(HeaviestPet pet in list)
+ {
+ Assert.AreEqual("Joe", pet.Name);
+ Assert.AreEqual(25, pet.Weight);
+ }
+ }
+ }
+
+ [Test]
+ public void CanGetSelectSubqueryWithSpecifiedParameter()
+ {
+ using (ISession s = OpenSession())
+ {
+ DetachedCriteria dc = DetachedCriteria.For<Person>().Add(Restrictions.Eq("Name", "Joe"))
+ .SetProjection(Projections.Max("Name"));
+ ICriteria c = s.CreateCriteria(typeof(Person))
+ .SetProjection(Projections.ProjectionList()
+ .Add(Projections.SubQuery(dc), "Name"))
+ .Add(Restrictions.Eq("Name", "Joe"));
+ c.SetResultTransformer(Transformers.AliasToBean(typeof(HeaviestPet)));
+ IList<HeaviestPet> list = c.List<HeaviestPet>();
+ Assert.AreEqual(1, list.Count);
+ foreach(HeaviestPet pet in list)
+ {
+ Assert.AreEqual("Joe", pet.Name);
+ }
+ }
+ }
+
+
+ [Test]
+ public void CanPageAndSortResultsWithParametersAndFilters()
+ {
+ using(ISession s = OpenSession())
+ {
+ s.EnableFilter("ExampleFilter").SetParameter("WeightVal", 100);
+ DetachedCriteria dc = DetachedCriteria.For<Person>().CreateCriteria("Pets", "pets")
+ .SetProjection(Projections.Max("pets.Weight"))
+ .Add(Restrictions.Eq("pets.Weight", 10.0));
+ ICriteria c = s.CreateCriteria(typeof(Person))
+ .SetProjection(Projections.ProjectionList()
+ .Add(Projections.SubQuery(dc), "Weight")
+ .Add(Projections.Property("Name"), "Name"))
+ .Add(Restrictions.Eq("Name", "Joe"));
+
+ c.SetResultTransformer(Transformers.AliasToBean(typeof(HeaviestPet)));
+ c.SetMaxResults(1);
+ c.AddOrder(new Order("Id", true));
+ IList<HeaviestPet> list = c.L...
[truncated message content] |
|
From: <fab...@us...> - 2008-07-21 04:50:01
|
Revision: 3642
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3642&view=rev
Author: fabiomaulo
Date: 2008-07-21 04:49:58 +0000 (Mon, 21 Jul 2008)
Log Message:
-----------
- Enabled <tuplizer> (NH-1397)
- Fix NH-1395
- Fix NH-1396
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Cfg/HbmConstants.cs
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs
trunk/nhibernate/src/NHibernate/EmptyInterceptor.cs
trunk/nhibernate/src/NHibernate/Engine/UnsavedValueFactory.cs
trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs
trunk/nhibernate/src/NHibernate/Mapping/PersistentClass.cs
trunk/nhibernate/src/NHibernate/Mapping/Subclass.cs
trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityEntityModeToTuplizerMapping.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Address.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Company.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Customer.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/DataProxyHandler.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/IProxyMarker.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/Customer.hbm.xml
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/InterceptorDynamicEntity.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/ProxyInterceptor.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Person.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/ProxyHelper.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/Customer.hbm.xml
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/EntityNameInterceptor.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/MyEntityInstantiator.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/MyEntityTuplizer.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/TuplizerDynamicEntity.cs
Modified: trunk/nhibernate/src/NHibernate/Cfg/HbmConstants.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/HbmConstants.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Cfg/HbmConstants.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -48,5 +48,6 @@
public const string nsResultset = nsPrefix + ":resultset";
public const string nsUnionSubclass = nsPrefix + ":union-subclass";
+ public const string nsTuplizer = nsPrefix + ":tuplizer";
}
}
Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -106,36 +106,32 @@
protected void BindClass(XmlNode node, PersistentClass model)
{
- string className = node.Attributes["name"] == null ? null : FullClassName(node.Attributes["name"].Value, mappings);
+ // transfer an explicitly defined entity name
+ // handle the lazy attribute
+ XmlAttribute lazyNode = node.Attributes["lazy"];
+ bool lazy = lazyNode == null ? mappings.DefaultLazy : "true".Equals(lazyNode.Value);
+ // go ahead and set the lazy here, since pojo.proxy can override it.
+ model.IsLazy = lazy;
- // CLASS
- model.ClassName = ClassForFullNameChecked(className, "persistent class {0} not found").AssemblyQualifiedName;
-
- string entityName = node.Attributes["entity-name"] == null ? null : node.Attributes["name"].Value;
+ string entityName = (node.Attributes["entity-name"] != null ? node.Attributes["entity-name"].Value : null)
+ ??
+ ClassForNameChecked(node.Attributes["name"].Value, mappings, "persistent class {0} not found").
+ FullName;
if (entityName == null)
- entityName = model.MappedClass.FullName;
- if (entityName == null)
{
throw new MappingException("Unable to determine entity name");
}
model.EntityName = entityName;
- // PROXY INTERFACE
- XmlAttribute proxyNode = node.Attributes["proxy"];
- XmlAttribute lazyNode = node.Attributes["lazy"];
- bool lazy = lazyNode == null ? mappings.DefaultLazy : "true".Equals(lazyNode.Value);
+ BindPocoRepresentation(node, model);
+ BindXmlRepresentation(node, model);
+ BindMapRepresentation(node, model);
- // go ahead and set the lazy here, since pojo.proxy can override it.
- model.IsLazy = lazy;
+ BindPersistentClassCommonValues(node, model);
+ }
- if (proxyNode != null)
- {
- model.ProxyInterfaceName = ClassForNameChecked(proxyNode.Value, mappings, "proxy class not found: {0}").AssemblyQualifiedName;
- model.IsLazy = true;
- }
- else if (model.IsLazy)
- model.ProxyInterfaceName = model.MappedClass.AssemblyQualifiedName;
-
+ private void BindPersistentClassCommonValues(XmlNode node, PersistentClass model)
+ {
// DISCRIMINATOR
XmlAttribute discriminatorNode = node.Attributes["discriminator-value"];
model.DiscriminatorValue = (discriminatorNode == null) ? model.EntityName : discriminatorNode.Value;
@@ -179,8 +175,8 @@
//persister = typeof( EntityPersister );
}
else
- model.EntityPersisterClass =
- ClassForNameChecked(persisterNode.Value, mappings, "could not instantiate persister class: {0}");
+ model.EntityPersisterClass = ClassForNameChecked(persisterNode.Value, mappings,
+ "could not instantiate persister class: {0}");
// CUSTOM SQL
HandleCustomSQL(node, model);
@@ -200,6 +196,71 @@
model.IsAbstract = isAbstract;
}
+ private void BindMapRepresentation(XmlNode node, PersistentClass entity)
+ {
+ XmlNode tuplizer = LocateTuplizerDefinition(node, EntityMode.Map);
+ if (tuplizer != null)
+ {
+ string tupClassName = FullClassName(tuplizer.Attributes["class"].Value, mappings);
+ entity.AddTuplizer(EntityMode.Map, tupClassName);
+ }
+ }
+
+ private void BindXmlRepresentation(XmlNode node, PersistentClass entity)
+ {
+ string nodeName = null;
+ XmlAttribute nodeAtt = node.Attributes["node"];
+ if(nodeAtt != null)
+ nodeName = nodeAtt.Value;
+ if (nodeName == null)
+ nodeName = StringHelper.Unqualify(entity.EntityName);
+ entity.NodeName = nodeName;
+
+ XmlNode tuplizer = LocateTuplizerDefinition(node, EntityMode.Xml);
+ if (tuplizer != null)
+ {
+ string tupClassName = FullClassName(tuplizer.Attributes["class"].Value, mappings);
+ entity.AddTuplizer(EntityMode.Xml, tupClassName);
+ }
+ }
+
+ private void BindPocoRepresentation(XmlNode node, PersistentClass entity)
+ {
+ string className = node.Attributes["name"] == null
+ ? null
+ : ClassForNameChecked(node.Attributes["name"].Value, mappings, "persistent class {0} not found").
+ AssemblyQualifiedName;
+
+ entity.ClassName = className;
+
+ XmlAttribute proxyNode = node.Attributes["proxy"];
+ if (proxyNode != null)
+ {
+ entity.ProxyInterfaceName = ClassForNameChecked(proxyNode.Value, mappings, "proxy class not found: {0}").AssemblyQualifiedName;
+ entity.IsLazy = true;
+ }
+ else if (entity.IsLazy)
+ entity.ProxyInterfaceName = className;
+
+ XmlNode tuplizer = LocateTuplizerDefinition(node, EntityMode.Poco);
+ if (tuplizer != null)
+ {
+ string tupClassName = FullClassName(tuplizer.Attributes["class"].Value, mappings);
+ entity.AddTuplizer(EntityMode.Poco, tupClassName);
+ }
+ }
+
+ private XmlNode LocateTuplizerDefinition(XmlNode container, EntityMode mode)
+ {
+ string modeToFind = EntityModeHelper.ToString(mode);
+ foreach (XmlNode node in container.SelectNodes(HbmConstants.nsTuplizer, namespaceManager))
+ {
+ if (modeToFind.Equals(node.Attributes["entity-mode"].Value))
+ return node;
+ }
+ return null;
+ }
+
private void BindJoin(XmlNode node, Join join)
{
PersistentClass persistentClass = join.PersistentClass;
@@ -1116,27 +1177,20 @@
private static string GetEntityName(XmlNode elem, Mappings model)
{
- // TODO: H3.2 Implement real entityName (look at IEntityPersister for feature)
- //string entityName = XmlHelper.GetAttributeValue(elem, "entity-name");
- //return entityName == null ? GetClassName( elem.Attributes[ "class" ], model ) : entityName;
- XmlAttribute att = elem.Attributes["class"];
+ string entityName = XmlHelper.GetAttributeValue(elem, "entity-name");
+ if (entityName == null)
+ {
+ XmlAttribute att = elem.Attributes["class"];
- if (att == null)
- return null;
+ return att == null ? null : GetClassName(att.Value, model);
+ }
+ else
+ {
+ return entityName;
+ }
- return GetClassName(att.Value, model);
}
- private static string GetQualifiedClassName(XmlNode elem, Mappings model)
- {
- XmlAttribute att = elem.Attributes["class"];
-
- if (att == null)
- return null;
-
- return GetQualifiedClassName(att.Value, model);
- }
-
protected XmlNodeList SelectNodes(XmlNode node, string xpath)
{
return node.SelectNodes(xpath, namespaceManager);
Modified: trunk/nhibernate/src/NHibernate/EmptyInterceptor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/EmptyInterceptor.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/EmptyInterceptor.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -58,7 +58,7 @@
return null;
}
- public string GetEntityName(object entity)
+ public virtual string GetEntityName(object entity)
{
return null;
}
Modified: trunk/nhibernate/src/NHibernate/Engine/UnsavedValueFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/UnsavedValueFactory.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Engine/UnsavedValueFactory.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -45,14 +45,11 @@
object defaultValue = identifierGetter.Get(Instantiate(constructor));
return new IdentifierValue(defaultValue);
}
- // TODO: NH - the branch below is actually never visited, so it's commented out
- /*
- else if( identifierGetter != null && ( identifierType is ValueTypeType ) )
+ else if (identifierGetter != null && (identifierType is PrimitiveType))
{
- object defaultValue = ( ( ValueTypeType ) identifierType ).DefaultValue;
- return new Cascades.IdentifierValue( defaultValue );
+ object defaultValue = ((PrimitiveType) identifierType).DefaultValue;
+ return new IdentifierValue(defaultValue);
}
- */
else
{
return IdentifierValue.SaveNull;
Modified: trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -730,6 +730,7 @@
/// <returns></returns>
public object Instantiate(IEntityPersister persister, object id)
{
+ ErrorIfClosed();
object result = interceptor.Instantiate(persister.EntityName, entityMode, id);
if (result == null)
{
Modified: trunk/nhibernate/src/NHibernate/Mapping/PersistentClass.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/PersistentClass.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Mapping/PersistentClass.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -59,7 +59,7 @@
private string temporaryIdTableName;
private string temporaryIdTableDDL;
- private IDictionary<EntityMode, System.Type> tuplizerImpls;
+ private IDictionary<EntityMode, string> tuplizerImpls;
private Versioning.OptimisticLock optimisticLockMode;
@@ -571,14 +571,11 @@
get { return temporaryIdTableDDL; }
}
- public virtual IDictionary<EntityMode, System.Type> TuplizerMap
+ public virtual IDictionary<EntityMode, string> TuplizerMap
{
get
{
- if (tuplizerImpls == null)
- return null;
-
- return new Dictionary<EntityMode, System.Type>(tuplizerImpls);
+ return tuplizerImpls == null ? null : new UnmodifiableDictionary<EntityMode, string>(tuplizerImpls);
}
}
@@ -1157,11 +1154,11 @@
get { return identifierMapper != null; }
}
- public void AddTuplizer(EntityMode entityMode, System.Type implClass)
+ public void AddTuplizer(EntityMode entityMode, string implClass)
{
if (tuplizerImpls == null)
{
- tuplizerImpls = new Dictionary<EntityMode, System.Type>();
+ tuplizerImpls = new Dictionary<EntityMode, string>();
}
tuplizerImpls[entityMode] = implClass;
}
@@ -1170,7 +1167,9 @@
{
if (tuplizerImpls == null)
return null;
- return tuplizerImpls[mode].AssemblyQualifiedName;
+ string result;
+ tuplizerImpls.TryGetValue(mode, out result);
+ return result;
}
public bool HasNaturalId()
Modified: trunk/nhibernate/src/NHibernate/Mapping/Subclass.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/Subclass.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Mapping/Subclass.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -161,19 +161,19 @@
get { return Superclass.FilterMap; }
}
- public override IDictionary<EntityMode, System.Type> TuplizerMap
+ public override IDictionary<EntityMode, string> TuplizerMap
{
get
{
- IDictionary<EntityMode, System.Type> specificTuplizerDefs = base.TuplizerMap;
- IDictionary<EntityMode, System.Type> superclassTuplizerDefs = Superclass.TuplizerMap;
+ IDictionary<EntityMode, string> specificTuplizerDefs = base.TuplizerMap;
+ IDictionary<EntityMode, string> superclassTuplizerDefs = Superclass.TuplizerMap;
if (specificTuplizerDefs == null && superclassTuplizerDefs == null)
{
return null;
}
else
{
- IDictionary<EntityMode, System.Type> combined = new Dictionary<EntityMode, System.Type>();
+ IDictionary<EntityMode, string> combined = new Dictionary<EntityMode, string>();
if (superclassTuplizerDefs != null)
{
ArrayHelper.AddAll(combined, superclassTuplizerDefs);
@@ -182,7 +182,7 @@
{
ArrayHelper.AddAll(combined, specificTuplizerDefs);
}
- return combined;
+ return new UnmodifiableDictionary<EntityMode, string>(combined);
}
}
}
Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityEntityModeToTuplizerMapping.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityEntityModeToTuplizerMapping.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityEntityModeToTuplizerMapping.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using NHibernate.Mapping;
+using NHibernate.Util;
namespace NHibernate.Tuple.Entity
{
@@ -25,19 +26,14 @@
public EntityEntityModeToTuplizerMapping(PersistentClass mappedEntity, EntityMetamodel em)
{
// create our own copy of the user-supplied tuplizer impl map
- Dictionary<EntityMode, System.Type> userSuppliedTuplizerImpls;
- if (mappedEntity.TuplizerMap != null)
- {
- userSuppliedTuplizerImpls = new Dictionary<EntityMode, System.Type>(mappedEntity.TuplizerMap);
- }
- else
- {
- userSuppliedTuplizerImpls = new Dictionary<EntityMode, System.Type>();
- }
+ Dictionary<EntityMode, string> userSuppliedTuplizerImpls = mappedEntity.TuplizerMap != null
+ ? new Dictionary<EntityMode, string>(
+ mappedEntity.TuplizerMap)
+ : new Dictionary<EntityMode, string>();
// Build the dynamic-map tuplizer...
ITuplizer dynamicMapTuplizer;
- System.Type tuplizerImpl;
+ string tuplizerImpl;
if (!userSuppliedTuplizerImpls.TryGetValue(EntityMode.Map, out tuplizerImpl))
{
dynamicMapTuplizer = new DynamicMapEntityTuplizer(em, mappedEntity);
@@ -51,7 +47,7 @@
// then the pojo tuplizer, using the dynamic-map tuplizer if no pojo representation is available
ITuplizer pojoTuplizer;
- System.Type tempObject2;
+ string tempObject2;
userSuppliedTuplizerImpls.TryGetValue(EntityMode.Poco, out tempObject2);
userSuppliedTuplizerImpls.Remove(EntityMode.Poco);
tuplizerImpl = tempObject2;
@@ -82,22 +78,23 @@
}
// then handle any user-defined entity modes...
- foreach (KeyValuePair<EntityMode, System.Type> pair in userSuppliedTuplizerImpls)
+ foreach (KeyValuePair<EntityMode, string> pair in userSuppliedTuplizerImpls)
{
IEntityTuplizer tuplizer = BuildEntityTuplizer(pair.Value, mappedEntity, em);
AddTuplizer(pair.Key, tuplizer);
}
}
- private static IEntityTuplizer BuildEntityTuplizer(System.Type implClass, PersistentClass pc, EntityMetamodel em)
+ private static IEntityTuplizer BuildEntityTuplizer(string className, PersistentClass pc, EntityMetamodel em)
{
try
{
+ System.Type implClass = ReflectHelper.ClassForName(className);
return (IEntityTuplizer)implClass.GetConstructor(entityTuplizerCTORSignature).Invoke(new object[] { em, pc });
}
catch (Exception t)
{
- throw new HibernateException("Could not build tuplizer [" + implClass.FullName + "]", t);
+ throw new HibernateException("Could not build tuplizer [" + className + "]", t);
}
}
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Address.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Address.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Address.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,10 @@
+namespace NHibernate.Test.DynamicEntity
+{
+ public interface Address
+ {
+ long Id { get; set;}
+ string Street { get; set;}
+ string City { get; set;}
+ string PostalCode { get; set;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Company.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Company.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Company.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,8 @@
+namespace NHibernate.Test.DynamicEntity
+{
+ public interface Company
+ {
+ long Id { get; set;}
+ string Name { get; set;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Customer.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Customer.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Customer.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,7 @@
+namespace NHibernate.Test.DynamicEntity
+{
+ public interface Customer:Person
+ {
+ Company Company { get; set;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/DataProxyHandler.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/DataProxyHandler.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/DataProxyHandler.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,59 @@
+using System.Collections;
+using Castle.Core.Interceptor;
+
+namespace NHibernate.Test.DynamicEntity
+{
+ public sealed class DataProxyHandler : Castle.Core.Interceptor.IInterceptor
+ {
+ private readonly Hashtable data = new Hashtable();
+ private readonly string entityName;
+
+ public DataProxyHandler(string entityName, object id)
+ {
+ this.entityName = entityName;
+ data["Id"] = id;
+ }
+
+ public string EntityName
+ {
+ get { return entityName; }
+ }
+
+ public Hashtable Data
+ {
+ get { return data; }
+ }
+
+ #region IInterceptor Members
+
+ public void Intercept(IInvocation invocation)
+ {
+ invocation.ReturnValue = null;
+ string methodName = invocation.Method.Name;
+ if ("get_DataHandler".Equals(methodName))
+ {
+ invocation.ReturnValue = this;
+ }
+ else if (methodName.StartsWith("set_"))
+ {
+ string propertyName = methodName.Substring(4);
+ data[propertyName] = invocation.Arguments[0];
+ }
+ else if (methodName.StartsWith("get_"))
+ {
+ string propertyName = methodName.Substring(4);
+ invocation.ReturnValue = data[propertyName];
+ }
+ else if ("ToString".Equals(methodName))
+ {
+ invocation.ReturnValue = entityName + "#" + data["Id"];
+ }
+ else if ("GetHashCode".Equals(methodName))
+ {
+ invocation.ReturnValue = GetHashCode();
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/IProxyMarker.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/IProxyMarker.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/IProxyMarker.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,7 @@
+namespace NHibernate.Test.DynamicEntity
+{
+ public interface IProxyMarker
+ {
+ DataProxyHandler DataHandler { get;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/Customer.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/Customer.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/Customer.hbm.xml 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8" ?>
+
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.DynamicEntity">
+
+ <!--
+ Mapping the Customer and Company interfaces. Our custom Interceptor
+ will be responsible for:
+ a) creating instances representing these interfaces;
+ b) determining the appropriate entity-name (i.e., which entity mapping to use) given an instance of one of these proxies.
+ -->
+ <class name="Person" table="t_person" abstract="false">
+ <!-- <class name="Person" table="t_person" discriminator-value="person"> -->
+ <id name="Id">
+ <generator class="native"/>
+ </id>
+ <discriminator force="false"/>
+ <property name="Name"/>
+
+ <many-to-one name="Address" cascade="all" column="addr_id"/>
+
+ <set name="Family" lazy="true" cascade="all">
+ <key column="pers_id"/>
+ <one-to-many class="Person"/>
+ </set>
+
+ <subclass name="Customer" discriminator-value="customer" abstract="false">
+ <many-to-one name="Company" cascade="none" column="comp_id"/>
+ </subclass>
+ </class>
+
+ <!-- Company interface mapping -->
+ <class name="Company" table="t_company" abstract="false">
+ <id name="Id">
+ <generator class="native"/>
+ </id>
+ <property name="Name"/>
+ </class>
+
+ <class name="Address" table="t_address" abstract="false">
+ <id name="Id">
+ <generator class="native"/>
+ </id>
+ <property name="Street"/>
+ <property name="City"/>
+ <property name="PostalCode"/>
+ </class>
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/InterceptorDynamicEntity.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/InterceptorDynamicEntity.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/InterceptorDynamicEntity.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,92 @@
+using System.Collections;
+using NHibernate.Cfg;
+using NUnit.Framework;
+
+namespace NHibernate.Test.DynamicEntity.Interceptor
+{
+ [TestFixture]
+ public class InterceptorDynamicEntity : TestCase
+ {
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override IList Mappings
+ {
+ get { return new string[] {"DynamicEntity.Interceptor.Customer.hbm.xml"}; }
+ }
+
+ protected override void Configure(Configuration configuration)
+ {
+ configuration.SetInterceptor(new ProxyInterceptor());
+ }
+
+ [Test]
+ public void It()
+ {
+ // Test saving these dyna-proxies
+ ISession session = OpenSession();
+ session.BeginTransaction();
+ Company company = ProxyHelper.NewCompanyProxy();
+ company.Name = "acme";
+ session.Save(company);
+ Customer customer = ProxyHelper.NewCustomerProxy();
+ customer.Name = "Steve";
+ customer.Company = company;
+ session.Save(customer);
+ session.Transaction.Commit();
+ session.Close();
+
+ Assert.IsNotNull(company.Id, "company id not assigned");
+ Assert.IsNotNull(customer.Id, "customer id not assigned");
+
+ // Test loading these dyna-proxies, along with flush processing
+ session = OpenSession();
+ session.BeginTransaction();
+ customer = session.Load<Customer>(customer.Id);
+ Assert.IsFalse(NHibernateUtil.IsInitialized(customer), "should-be-proxy was initialized");
+
+ customer.Name = "other";
+ session.Flush();
+ Assert.IsFalse(NHibernateUtil.IsInitialized(customer.Company), "should-be-proxy was initialized");
+
+ session.Refresh(customer);
+ Assert.AreEqual("other", customer.Name, "name not updated");
+ Assert.AreEqual("acme", customer.Company.Name, "company association not correct");
+
+ session.Transaction.Commit();
+ session.Close();
+
+ // Test detached entity re-attachment with these dyna-proxies
+ customer.Name = "Steve";
+ session = OpenSession();
+ session.BeginTransaction();
+ session.Update(customer);
+ session.Flush();
+ session.Refresh(customer);
+ Assert.AreEqual("Steve", customer.Name, "name not updated");
+ session.Transaction.Commit();
+ session.Close();
+
+ // Test querying
+ session = OpenSession();
+ session.BeginTransaction();
+ int count = session.CreateQuery("from Customer").List().Count;
+ Assert.AreEqual(1, count, "querying dynamic entity");
+ session.Clear();
+ count = session.CreateQuery("from Person").List().Count;
+ Assert.AreEqual(1, count, "querying dynamic entity");
+ session.Transaction.Commit();
+ session.Close();
+
+ // test deleteing
+ session = OpenSession();
+ session.BeginTransaction();
+ session.Delete(company);
+ session.Delete(customer);
+ session.Transaction.Commit();
+ session.Close();
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/ProxyInterceptor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/ProxyInterceptor.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/ProxyInterceptor.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,27 @@
+namespace NHibernate.Test.DynamicEntity.Interceptor
+{
+ public class ProxyInterceptor : EmptyInterceptor
+ {
+ public override string GetEntityName(object entity)
+ {
+ string entityName = ProxyHelper.ExtractEntityName(entity) ?? base.GetEntityName(entity);
+ return entityName;
+ }
+
+ public override object Instantiate(string entityName, EntityMode entityMode, object id)
+ {
+ if (entityMode == EntityMode.Poco)
+ {
+ if (typeof(Customer).FullName.Equals(entityName))
+ {
+ return ProxyHelper.NewCustomerProxy(id);
+ }
+ else if (typeof(Company).FullName.Equals(entityName))
+ {
+ return ProxyHelper.NewCompanyProxy(id);
+ }
+ }
+ return base.Instantiate(entityName, entityMode, id);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Person.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Person.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Person.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,12 @@
+using Iesi.Collections.Generic;
+
+namespace NHibernate.Test.DynamicEntity
+{
+ public interface Person
+ {
+ long Id { get; set;}
+ string Name { get; set;}
+ Address Address { get;set;}
+ ISet<Person> Family { get; set;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/ProxyHelper.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/ProxyHelper.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/ProxyHelper.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,79 @@
+using Castle.DynamicProxy;
+
+namespace NHibernate.Test.DynamicEntity
+{
+ public class ProxyHelper
+ {
+ private static readonly ProxyGenerator proxyGenerator = new ProxyGenerator();
+
+ public static Person NewPersonProxy()
+ {
+ return NewPersonProxy(0L);
+ }
+
+ public static Person NewPersonProxy(object id)
+ {
+ return
+ (Person)
+ proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof (Person),
+ new System.Type[] {typeof (IProxyMarker), typeof (Person)},
+ new DataProxyHandler(typeof (Person).FullName, id));
+ }
+
+ public static Customer NewCustomerProxy()
+ {
+ return NewCustomerProxy(0L);
+ }
+
+ public static Customer NewCustomerProxy(object id)
+ {
+ return
+ (Customer)
+ proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof (Customer),
+ new System...
[truncated message content] |
|
From: <fab...@us...> - 2008-07-21 05:23:51
|
Revision: 3643
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3643&view=rev
Author: fabiomaulo
Date: 2008-07-21 05:23:55 +0000 (Mon, 21 Jul 2008)
Log Message:
-----------
Breaking Change : The EntityMode accessible from ISession (NH-1398)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/ISession.cs
trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs
Modified: trunk/nhibernate/src/NHibernate/ISession.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/ISession.cs 2008-07-21 04:49:58 UTC (rev 3642)
+++ trunk/nhibernate/src/NHibernate/ISession.cs 2008-07-21 05:23:55 UTC (rev 3643)
@@ -70,6 +70,9 @@
/// </remarks>
public interface ISession : IDisposable
{
+ /// <summary> The entity mode in effect for this session.</summary>
+ EntityMode ActiveEntityMode { get;} // NH different implementation: changend name to don't have conflicts
+
/// <summary>
/// Force the <c>ISession</c> to flush.
/// </summary>
Modified: trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2008-07-21 04:49:58 UTC (rev 3642)
+++ trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2008-07-21 05:23:55 UTC (rev 3643)
@@ -1921,6 +1921,11 @@
get { return entityMode; }
}
+ public EntityMode ActiveEntityMode
+ {
+ get { return entityMode; }
+ }
+
public override string FetchProfile
{
get { return fetchProfile; }
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-07-21 15:21:29
|
Revision: 3644
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3644&view=rev
Author: fabiomaulo
Date: 2008-07-21 15:21:34 +0000 (Mon, 21 Jul 2008)
Log Message:
-----------
- Support for EntityMode.Map (NH-1401)
- Support DefaultEntityMode in Settings (NH-1401)
- Support Cache for Dynamic entities (NH-1402)
BREAKING CHANGE:
- see Configuration.cs for method related with Cache Concurrency Strategy
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Cfg/ClassExtractor.cs
trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs
trunk/nhibernate/src/NHibernate/Cfg/Environment.cs
trunk/nhibernate/src/NHibernate/Cfg/MappingsQueueEntry.cs
trunk/nhibernate/src/NHibernate/Cfg/SettingsFactory.cs
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassIdBinder.cs
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/CollectionBinder.cs
trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs
trunk/nhibernate/src/NHibernate/nhibernate-configuration.xsd
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
trunk/nhibernate/src/NHibernate.Test/TestCase.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/EntityModeTest/
trunk/nhibernate/src/NHibernate.Test/EntityModeTest/Map/
trunk/nhibernate/src/NHibernate.Test/EntityModeTest/Map/Basic/
trunk/nhibernate/src/NHibernate.Test/EntityModeTest/Map/Basic/DynamicClassFixture.cs
trunk/nhibernate/src/NHibernate.Test/EntityModeTest/Map/Basic/ProductLine.hbm.xml
Modified: trunk/nhibernate/src/NHibernate/Cfg/ClassExtractor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/ClassExtractor.cs 2008-07-21 05:23:55 UTC (rev 3643)
+++ trunk/nhibernate/src/NHibernate/Cfg/ClassExtractor.cs 2008-07-21 15:21:34 UTC (rev 3644)
@@ -1,4 +1,3 @@
-using System;
using System.Collections;
using System.Xml;
using Iesi.Collections;
@@ -23,7 +22,7 @@
public ClassEntry(string extends, string className, string assembly, string @namespace)
{
_fullExtends = extends == null ? null : TypeNameParser.Parse(extends, @namespace, assembly);
- _fullClassName = TypeNameParser.Parse(className, @namespace, assembly);
+ _fullClassName = className == null ? null : TypeNameParser.Parse(className, @namespace, assembly);
}
public AssemblyQualifiedTypeName FullExtends
Modified: trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2008-07-21 05:23:55 UTC (rev 3643)
+++ trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2008-07-21 15:21:34 UTC (rev 3644)
@@ -444,25 +444,25 @@
/// </summary>
public Mappings CreateMappings(Dialect.Dialect dialect)
{
- return new Mappings(classes,
- collections,
- tables,
- namedQueries,
- namedSqlQueries,
- sqlResultSetMappings,
- imports,
- secondPasses,
- propertyReferences,
- namingStrategy,
- typeDefs,
- filterDefinitions,
- extendsQueue,
- auxiliaryDatabaseObjects,
- tableNameBinding,
+ return new Mappings(classes,
+ collections,
+ tables,
+ namedQueries,
+ namedSqlQueries,
+ sqlResultSetMappings,
+ imports,
+ secondPasses,
+ propertyReferences,
+ namingStrategy,
+ typeDefs,
+ filterDefinitions,
+ extendsQueue,
+ auxiliaryDatabaseObjects,
+ tableNameBinding,
columnNameBindingPerTable,
defaultAssembly,
defaultNamespace,
- dialect
+ dialect
);
}
@@ -1291,19 +1291,9 @@
// Load class-cache
foreach (ClassCacheConfiguration ccc in hc.SessionFactory.ClassesCache)
{
- System.Type clazz;
- try
- {
- clazz = ReflectHelper.ClassForName(ccc.Class);
- }
- catch (TypeLoadException tle)
- {
- throw new HibernateConfigException("class-cache Configuration: Could not find class " + ccc.Class, tle);
- }
-
string region = string.IsNullOrEmpty(ccc.Region) ? ccc.Class : ccc.Region;
bool includeLazy = (ccc.Include != ClassCacheInclude.NonLazy);
- SetCacheConcurrencyStrategy(clazz, CfgXmlHelper.ClassCacheUsageConvertToString(ccc.Usage), region, includeLazy);
+ SetCacheConcurrencyStrategy(ccc.Class, CfgXmlHelper.ClassCacheUsageConvertToString(ccc.Usage), region, includeLazy);
}
// Load collection-cache
@@ -1317,7 +1307,7 @@
}
string region = string.IsNullOrEmpty(ccc.Region) ? role : ccc.Region;
- SetCacheConcurrencyStrategy(role, CfgXmlHelper.ClassCacheUsageConvertToString(ccc.Usage), region);
+ SetCollectionCacheConcurrencyStrategy(role, CfgXmlHelper.ClassCacheUsageConvertToString(ccc.Usage), region);
}
// Events
@@ -1347,6 +1337,20 @@
return this;
}
+ internal RootClass GetRootClassMapping(string clazz)
+ {
+ try
+ {
+ return (RootClass)GetClassMapping(clazz);
+ }
+ catch (InvalidCastException)
+ {
+ throw new HibernateConfigException(
+ "class-cache Configuration: You may only specify a cache for root <class> mappings "
+ + "(cache was specified for " + clazz + ")");
+ }
+ }
+
internal RootClass GetRootClassMapping(System.Type clazz)
{
PersistentClass persistentClass = GetClassMapping(clazz);
@@ -1371,36 +1375,40 @@
/// <summary>
/// Set up a cache for an entity class
/// </summary>
- public Configuration SetCacheConcurrencyStrategy(System.Type clazz, string concurrencyStrategy)
+ public Configuration SetCacheConcurrencyStrategy(String clazz, String concurrencyStrategy)
{
- SetCacheConcurrencyStrategy(clazz, concurrencyStrategy, clazz.FullName);
+ SetCacheConcurrencyStrategy(clazz, concurrencyStrategy, clazz);
return this;
}
- internal void SetCacheConcurrencyStrategy(System.Type clazz, string concurrencyStrategy, string region)
+ public void SetCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region)
{
SetCacheConcurrencyStrategy(clazz, concurrencyStrategy, region, true);
}
- internal void SetCacheConcurrencyStrategy(System.Type clazz, string concurrencyStrategy,
- string region, bool includeLazy)
+ internal void SetCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region, bool includeLazy)
{
- RootClass rootClass = GetRootClassMapping(clazz);
+ RootClass rootClass = GetRootClassMapping(StringHelper.GetFullClassname(clazz));
+ if (rootClass == null)
+ {
+ throw new HibernateConfigException("Cannot cache an unknown entity: " + clazz);
+ }
rootClass.CacheConcurrencyStrategy = concurrencyStrategy;
rootClass.CacheRegionName = region;
rootClass.SetLazyPropertiesCacheable(includeLazy);
}
+
/// <summary>
/// Set up a cache for a collection role
/// </summary>
- public Configuration SetCacheConcurrencyStrategy(string collectionRole, string concurrencyStrategy)
+ public Configuration SetCollectionCacheConcurrencyStrategy(string collectionRole, string concurrencyStrategy)
{
- SetCacheConcurrencyStrategy(collectionRole, concurrencyStrategy, collectionRole);
+ SetCollectionCacheConcurrencyStrategy(collectionRole, concurrencyStrategy, collectionRole);
return this;
}
- internal void SetCacheConcurrencyStrategy(string collectionRole, string concurrencyStrategy, string region)
+ internal void SetCollectionCacheConcurrencyStrategy(string collectionRole, string concurrencyStrategy, string region)
{
NHibernate.Mapping.Collection collection = GetCollectionMapping(collectionRole);
collection.CacheConcurrencyStrategy = concurrencyStrategy;
@@ -1613,7 +1621,7 @@
else
{
object[] listeners =
- (object[]) System.Array.CreateInstance(eventListeners.GetListenerClassFor(type), listenerClasses.Length);
+ (object[])System.Array.CreateInstance(eventListeners.GetListenerClassFor(type), listenerClasses.Length);
for (int i = 0; i < listeners.Length; i++)
{
try
@@ -1657,88 +1665,88 @@
switch (type)
{
case ListenerType.Autoflush:
- eventListeners.AutoFlushEventListeners = new IAutoFlushEventListener[] { };
+ eventListeners.AutoFlushEventListeners = new IAutoFlushEventListener[] { };
break;
case ListenerType.Merge:
- eventListeners.MergeEventListeners = new IMergeEventListener[] { };
+ eventListeners.MergeEventListeners = new IMergeEventListener[] { };
break;
case ListenerType.Create:
- eventListeners.PersistEventListeners = new IPersistEventListener[] { };
+ eventListeners.PersistEventListeners = new IPersistEventListener[] { };
break;
case ListenerType.CreateOnFlush:
- eventListeners.PersistOnFlushEventListeners = new IPersistEventListener[] { };
+ eventListeners.PersistOnFlushEventListeners = new IPersistEventListener[] { };
break;
case ListenerType.Delete:
- eventListeners.DeleteEventListeners = new IDeleteEventListener[] { };
+ eventListeners.DeleteEventListeners = new IDeleteEventListener[] { };
break;
case ListenerType.DirtyCheck:
- eventListeners.DirtyCheckEventListeners = new IDirtyCheckEventListener[] { };
+ eventListeners.DirtyCheckEventListeners = new IDirtyCheckEventListener[] { };
break;
case ListenerType.Evict:
- eventListeners.EvictEventListeners = new IEvictEventListener[] { };
+ eventListeners.EvictEventListeners = new IEvictEventListener[] { };
break;
case ListenerType.Flush:
- eventListeners.FlushEventListeners = new IFlushEventListener[] { };
+ eventListeners.FlushEventListeners = new IFlushEventListener[] { };
break;
case ListenerType.FlushEntity:
- eventListeners.FlushEntityEventListeners = new IFlushEntityEventListener[] { };
+ eventListeners.FlushEntityEventListeners = new IFlushEntityEventListener[] { };
break;
case ListenerType.Load:
- eventListeners.LoadEventListeners = new ILoadEventListener[] { };
+ eventListeners.LoadEventListeners = new ILoadEventListener[] { };
break;
case ListenerType.LoadCollection:
- eventListeners.InitializeCollectionEventListeners = new IInitializeCollectionEventListener[] { };
+ eventListeners.InitializeCollectionEventListeners = new IInitializeCollectionEventListener[] { };
break;
case ListenerType.Lock:
- eventListeners.LockEventListeners = new ILockEventListener[] { };
+ eventListeners.LockEventListeners = new ILockEventListener[] { };
break;
case ListenerType.Refresh:
- eventListeners.RefreshEventListeners = new IRefreshEventListener[] { };
+ eventListeners.RefreshEventListeners = new IRefreshEventListener[] { };
break;
case ListenerType.Replicate:
- eventListeners.ReplicateEventListeners = new IReplicateEventListener[] { };
+ eventListeners.ReplicateEventListeners = new IReplicateEventListener[] { };
break;
case ListenerType.SaveUpdate:
- eventListeners.SaveOrUpdateEventListeners = new ISaveOrUpdateEventListener[] { };
+ eventListeners.SaveOrUpdateEventListeners = new ISaveOrUpdateEventListener[] { };
break;
case ListenerType.Save:
- eventListeners.SaveEventListeners = new ISaveOrUpdateEventListener[] { };
+ eventListeners.SaveEventListeners = new ISaveOrUpdateEventListener[] { };
break;
case ListenerType.PreUpdate:
- eventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] { };
+ eventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] { };
break;
case ListenerType.Update:
- eventListeners.UpdateEventListeners = new ISaveOrUpdateEventListener[] { };
+ eventListeners.UpdateEventListeners = new ISaveOrUpdateEventListener[] { };
break;
case ListenerType.PreLoad:
- eventListeners.PreLoadEventListeners = new IPreLoadEventListener[] { };
+ eventListeners.PreLoadEventListeners = new IPreLoadEventListener[] { };
break;
case ListenerType.PreDelete:
- eventListeners.PreDeleteEventListeners = new IPreDeleteEventListener[] { };
+ eventListeners.PreDeleteEventListeners = new IPreDeleteEventListener[] { };
break;
case ListenerType.PreInsert:
- eventListeners.PreInsertEventListeners = new IPreInsertEventListener[] { };
+ eventListeners.PreInsertEventListeners = new IPreInsertEventListener[] { };
break;
case ListenerType.PostLoad:
- eventListeners.PostLoadEventListeners = new IPostLoadEventListener[] { };
+ eventListeners.PostLoadEventListeners = new IPostLoadEventListener[] { };
break;
case ListenerType.PostInsert:
- eventListeners.PostInsertEventListeners = new IPostInsertEventListener[] { };
+ eventListeners.PostInsertEventListeners = new IPostInsertEventListener[] { };
break;
case ListenerType.PostUpdate:
- eventListeners.PostUpdateEventListeners = new IPostUpdateEventListener[] { };
+ eventListeners.PostUpdateEventListeners = new IPostUpdateEventListener[] { };
break;
case ListenerType.PostDelete:
- eventListeners.PostDeleteEventListeners = new IPostDeleteEventListener[] { };
+ eventListeners.PostDeleteEventListeners = new IPostDeleteEventListener[] { };
break;
case ListenerType.PostCommitUpdate:
- eventListeners.PostCommitUpdateEventListeners = new IPostUpdateEventListener[] { };
+ eventListeners.PostCommitUpdateEventListeners = new IPostUpdateEventListener[] { };
break;
case ListenerType.PostCommitInsert:
- eventListeners.PostCommitInsertEventListeners = new IPostInsertEventListener[] { };
+ eventListeners.PostCommitInsertEventListeners = new IPostInsertEventListener[] { };
break;
case ListenerType.PostCommitDelete:
- eventListeners.PostCommitDeleteEventListeners = new IPostDeleteEventListener[] { };
+ eventListeners.PostCommitDeleteEventListeners = new IPostDeleteEventListener[] { };
break;
default:
log.Warn("Unrecognized listener type [" + type + "]");
@@ -1760,88 +1768,88 @@
switch (type)
{
case ListenerType.Autoflush:
- eventListeners.AutoFlushEventListeners = (IAutoFlushEventListener[]) listeners;
+ eventListeners.AutoFlushEventListeners = (IAutoFlushEventListener[])listeners;
break;
case ListenerType.Merge:
- eventListeners.MergeEventListeners = (IMergeEventListener[])listeners;
+ eventListeners.MergeEventListeners = (IMergeEventListener[])listeners;
break;
case ListenerType.Create:
- eventListeners.PersistEventListeners = (IPersistEventListener[])listeners;
+ eventListeners.PersistEventListeners = (IPersistEventListener[])listeners;
break;
case ListenerType.CreateOnFlush:
- eventListeners.PersistOnFlushEventListeners = (IPersistEventListener[])listeners;
+ eventListeners.PersistOnFlushEventListeners = (IPersistEventListener[])listeners;
break;
case ListenerType.Delete:
- eventListeners.DeleteEventListeners = (IDeleteEventListener[])listeners;
+ eventListeners.DeleteEventListeners = (IDeleteEventListener[])listeners;
break;
case ListenerType.DirtyCheck:
- eventListeners.DirtyCheckEventListeners = (IDirtyCheckEventListener[])listeners;
+ eventListeners.DirtyCheckEventListeners = (IDirtyCheckEventListener[])listeners;
break;
case ListenerType.Evict:
- eventListeners.EvictEventListeners = (IEvictEventListener[])listeners;
+ eventListeners.EvictEventListeners = (IEvictEventListener[])listeners;
break;
case ListenerType.Flush:
- eventListeners.FlushEventListeners = (IFlushEventListener[])listeners;
+ eventListeners.FlushEventListeners = (IFlushEventListener[])listeners;
break;
case ListenerType.FlushEntity:
- eventListeners.FlushEntityEventListeners = (IFlushEntityEventListener[])listeners;
+ eventListeners.FlushEntityEventListeners = (IFlushEntityEventListener[])listeners;
break;
case ListenerType.Load:
- eventListeners.LoadEventListeners = (ILoadEventListener[])listeners;
+ eventListeners.LoadEventListeners = (ILoadEventListener[])listeners;
break;
case ListenerType.LoadCollection:
- eventListeners.InitializeCollectionEventListeners = (IInitializeCollectionEventListener[])listeners;
+ eventListeners.InitializeCollectionEventListeners = (IInitializeCollectionEventListener[])listeners;
break;
case ListenerType.Lock:
- eventListeners.LockEventListeners = (ILockEventListener[])listeners;
+ eventListeners.LockEventListeners = (ILockEventListener[])listeners;
break;
case ListenerType.Refresh:
- eventListeners.RefreshEventListeners = (IRefreshEventListener[])listeners;
+ eventListeners.RefreshEventListeners = (IRefreshEventListener[])listeners;
break;
case ListenerType.Replicate:
- eventListeners.ReplicateEventListeners = (IReplicateEventListener[])listeners;
+ eventListeners.ReplicateEventListeners = (IReplicateEventListener[])listeners;
break;
case ListenerType.SaveUpdate:
- eventListeners.SaveOrUpdateEventListeners = (ISaveOrUpdateEventListener[])listeners;
+ eventListeners.SaveOrUpdateEventListeners = (ISaveOrUpdateEventListener[])listeners;
break;
case ListenerType.Save:
- eventListeners.SaveEventListeners = (ISaveOrUpdateEventListener[])listeners;
+ eventListeners.SaveEventListeners = (ISaveOrUpdateEventListener[])listeners;
break;
case ListenerType.PreUpdate:
- eventListeners.PreUpdateEventListeners = (IPreUpdateEventListener[])listeners;
+ eventListeners.PreUpdateEventListeners = (IPreUpdateEventListener[])listeners;
break;
case ListenerType.Update:
- eventListeners.UpdateEventListeners = (ISaveOrUpdateEventListener[])listeners;
+ eventListeners.UpdateEventListeners = (ISaveOrUpdateEventListener[])listeners;
break;
case ListenerType.PreLoad:
- eventListeners.PreLoadEventListeners = (IPreLoadEventListener[])listeners;
+ eventListeners.PreLoadEventListeners = (IPreLoadEventListener[])listeners;
break;
case ListenerType.PreDelete:
- eventListeners.PreDeleteEventListeners = (IPreDeleteEventListener[])listeners;
+ eventListeners.PreDeleteEventListeners = (IPreDeleteEventListener[])listeners;
break;
case ListenerType.PreInsert:
- eventListeners.PreInsertEventListeners = (IPreInsertEventListener[])listeners;
+ eventListeners.PreInsertEventListeners = (IPreInsertEventListener[])listeners;
break;
case ListenerType.PostLoad:
- eventListeners.PostLoadEventListeners = (IPostLoadEventListener[])listeners;
+ eventListeners.PostLoadEventListeners = (IPostLoadEventListener[])listeners;
break;
case ListenerType.PostInsert:
- eventListeners.PostInsertEventListeners = (IPostInsertEventListener[])listeners;
+ eventListeners.PostInsertEventListeners = (IPostInsertEventListener[])listeners;
break;
case ListenerType.PostUpdate:
- eventListeners.PostUpdateEventListeners = (IPostUpdateEventListener[])listeners;
+ eventListeners.PostUpdateEventListeners = (IPostUpdateEventListener[])listeners;
break;
case ListenerType.PostDelete:
- eventListeners.PostDeleteEventListeners = (IPostDeleteEventListener[])listeners;
+ eventListeners.PostDeleteEventListeners = (IPostDeleteEventListener[])listeners;
break;
case ListenerType.PostCommitUpdate:
- eventListeners.PostCommitUpdateEventListeners = (IPostUpdateEventListener[])listeners;
+ eventListeners.PostCommitUpdateEventListeners = (IPostUpdateEventListener[])listeners;
break;
case ListenerType.PostCommitInsert:
- eventListeners.PostCommitInsertEventListeners = (IPostInsertEventListener[])listeners;
+ eventListeners.PostCommitInsertEventListeners = (IPostInsertEventListener[])listeners;
break;
case ListenerType.PostCommitDelete:
- eventListeners.PostCommitDeleteEventListeners = (IPostDeleteEventListener[])listeners;
+ eventListeners.PostCommitDeleteEventListeners = (IPostDeleteEventListener[])listeners;
break;
default:
log.Warn("Unrecognized listener type [" + type + "]");
@@ -1865,7 +1873,7 @@
{
if (table.IsPhysicalTable)
{
- ITableMetadata tableInfo = databaseMetadata.GetTableMetadata(table.Name, table.Schema ?? defaultSchema,
+ ITableMetadata tableInfo = databaseMetadata.GetTableMetadata(table.Name, table.Schema ?? defaultSchema,
table.Catalog ?? defaultCatalog, table.IsQuoted);
if (tableInfo == null)
{
@@ -1897,7 +1905,7 @@
if (fk.HasPhysicalConstraint)
{
bool create = tableInfo == null || (
- tableInfo.GetForeignKeyMetadata(fk.Name) == null &&
+ tableInfo.GetForeignKeyMetadata(fk.Name) == null &&
(!(dialect is MySQLDialect) || tableInfo.GetIndexMetadata(fk.Name) == null)
);
if (create)
@@ -1939,7 +1947,7 @@
if (!pc.IsInherited)
{
IPersistentIdentifierGenerator ig =
- pc.Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema, (RootClass) pc) as
+ pc.Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema, (RootClass)pc) as
IPersistentIdentifierGenerator;
if (ig != null)
@@ -1952,8 +1960,8 @@
if (collection.IsIdentified)
{
IPersistentIdentifierGenerator ig =
- ((IdentifierCollection) collection).Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema,
- null) as IPersistentIdentifierGenerator;
+ ((IdentifierCollection)collection).Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema,
+ null) as IPersistentIdentifierGenerator;
if (ig != null)
generators[ig.GeneratorKey()] = ig;
Modified: trunk/nhibernate/src/NHibernate/Cfg/Environment.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/Environment.cs 2008-07-21 05:23:55 UTC (rev 3643)
+++ trunk/nhibernate/src/NHibernate/Cfg/Environment.cs 2008-07-21 15:21:34 UTC (rev 3644)
@@ -49,8 +49,8 @@
{
Assembly thisAssembly = Assembly.GetExecutingAssembly();
AssemblyInformationalVersionAttribute[] attrs = (AssemblyInformationalVersionAttribute[])
- thisAssembly.GetCustomAttributes(
- typeof(AssemblyInformationalVersionAttribute), false);
+ thisAssembly.GetCustomAttributes(
+ typeof(AssemblyInformationalVersionAttribute), false);
if (attrs != null && attrs.Length > 0)
{
@@ -85,6 +85,9 @@
/// <summary> A default database catalog name to use for unqualified tablenames</summary>
public const string DefaultCatalog = "default_catalog";
+ /// <summary>The EntityMode in which set the Session opened from the SessionFactory.</summary>
+ public const string DefaultEntityMode = "default_entity_mode";
+
public const string ShowSql = "show_sql";
public const string MaxFetchDepth = "max_fetch_depth";
public const string CurrentSessionContextClass = "current_session_context_class";
@@ -192,7 +195,7 @@
if (config == null)
{
- log.Info(string.Format("{0} section not found in application configuration file",CfgXmlHelper.CfgSectionName));
+ log.Info(string.Format("{0} section not found in application configuration file", CfgXmlHelper.CfgSectionName));
return;
}
@@ -246,7 +249,7 @@
/// </remarks>
public static IDictionary<string, string> Properties
{
- get { return new Dictionary<string,string>(GlobalProperties); }
+ get { return new Dictionary<string, string>(GlobalProperties); }
}
[Obsolete]
@@ -293,7 +296,7 @@
{
string defaultBytecodeProvider = "lcg";
string provider = PropertiesHelper.GetString(PropertyBytecodeProvider, properties,
- defaultBytecodeProvider);
+ defaultBytecodeProvider);
log.Info("Bytecode provider name : " + provider);
return BuildBytecodeProvider(provider);
}
Modified: trunk/nhibernate/src/NHibernate/Cfg/MappingsQueueEntry.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/MappingsQueueEntry.cs 2008-07-21 05:23:55 UTC (rev 3643)
+++ trunk/nhibernate/src/NHibernate/Cfg/MappingsQueueEntry.cs 2008-07-21 15:21:34 UTC (rev 3644)
@@ -33,7 +33,8 @@
foreach (ClassExtractor.ClassEntry ce in classEntries)
{
- result.Add(ce.FullClassName);
+ if (ce.FullClassName != null)
+ result.Add(ce.FullClassName);
}
return result;
@@ -69,4 +70,4 @@
get { return containedClassNames; }
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Cfg/SettingsFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/SettingsFactory.cs 2008-07-21 05:23:55 UTC (rev 3643)
+++ trunk/nhibernate/src/NHibernate/Cfg/SettingsFactory.cs 2008-07-21 15:21:34 UTC (rev 3644)
@@ -99,12 +99,12 @@
log.Info("Default schema: " + defaultSchema);
if (defaultCatalog != null)
log.Info("Default catalog: " + defaultCatalog);
- settings.DefaultSchemaName=defaultSchema;
- settings.DefaultCatalogName=defaultCatalog;
+ settings.DefaultSchemaName = defaultSchema;
+ settings.DefaultCatalogName = defaultCatalog;
int batchFetchSize = PropertiesHelper.GetInt32(Environment.DefaultBatchFetchSize, properties, 1);
log.Info("Default batch fetch size: " + batchFetchSize);
- settings.DefaultBatchFetchSize= batchFetchSize;
+ settings.DefaultBatchFetchSize = batchFetchSize;
//Statistics and logging:
@@ -126,11 +126,11 @@
settings.QueryTranslatorFactory = CreateQueryTranslatorFactory(properties);
- IDictionary<string, string> querySubstitutions =
- PropertiesHelper.ToDictionary(Environment.QuerySubstitutions, " ,=;:\n\t\r\f", properties);
+ IDictionary<string, string> querySubstitutions = PropertiesHelper.ToDictionary(Environment.QuerySubstitutions,
+ " ,=;:\n\t\r\f", properties);
if (log.IsInfoEnabled)
{
- log.Info("Query language substitutions: " + CollectionPrinter.ToString((IDictionary)querySubstitutions));
+ log.Info("Query language substitutions: " + CollectionPrinter.ToString((IDictionary) querySubstitutions));
}
string autoSchemaExport = PropertiesHelper.GetString(Environment.Hbm2ddlAuto, properties, null);
@@ -169,13 +169,13 @@
if (useQueryCache)
{
- string queryCacheFactoryClassName =
- PropertiesHelper.GetString(Environment.QueryCacheFactory, properties, typeof(StandardQueryCacheFactory).FullName);
+ string queryCacheFactoryClassName = PropertiesHelper.GetString(Environment.QueryCacheFactory, properties,
+ typeof (StandardQueryCacheFactory).FullName);
log.Info("query cache factory: " + queryCacheFactoryClassName);
try
{
- settings.QueryCacheFactory = (IQueryCacheFactory) Activator.CreateInstance(
- ReflectHelper.ClassForName(queryCacheFactoryClassName));
+ settings.QueryCacheFactory =
+ (IQueryCacheFactory) Activator.CreateInstance(ReflectHelper.ClassForName(queryCacheFactoryClassName));
}
catch (Exception cnfe)
{
@@ -200,18 +200,23 @@
{
try
{
- isolation = (IsolationLevel) Enum.Parse(typeof(IsolationLevel), isolationString);
+ isolation = (IsolationLevel) Enum.Parse(typeof (IsolationLevel), isolationString);
log.Info("Using Isolation Level: " + isolation);
}
catch (ArgumentException ae)
{
log.Error("error configuring IsolationLevel " + isolationString, ae);
throw new HibernateException(
- "The isolation level of " + isolationString + " is not a valid IsolationLevel. Please " +
- "use one of the Member Names from the IsolationLevel.", ae);
+ "The isolation level of " + isolationString + " is not a valid IsolationLevel. Please "
+ + "use one of the Member Names from the IsolationLevel.", ae);
}
}
+ EntityMode defaultEntityMode =
+ EntityModeHelper.Parse(PropertiesHelper.GetString(Environment.DefaultEntityMode, properties, "poco"));
+ log.Info("Default entity-mode: " + defaultEntityMode);
+ settings.DefaultEntityMode = defaultEntityMode;
+
bool namedQueryChecking = PropertiesHelper.GetBoolean(Environment.QueryStartupChecking, properties, true);
log.Info("Named query checking : " + EnabledDisabled(namedQueryChecking));
settings.IsNamedQueryStartupCheckingEnabled = namedQueryChecking;
Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs 2008-07-21 05:23:55 UTC (rev 3643)
+++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs 2008-07-21 15:21:34 UTC (rev 3644)
@@ -147,9 +147,11 @@
// IMPORT
// For entities, the EntityName is the key to find a persister
// NH Different behavior: we are using the association between EntityName and its more certain implementation (AssemblyQualifiedName)
- mappings.AddImport(model.MappedClass.AssemblyQualifiedName, model.EntityName);
+ // Dynamic entities have no class, reverts to EntityName. -AK
+ string qualifiedName = model.MappedClass == null ? model.EntityName : model.MappedClass.AssemblyQualifiedName;
+ mappings.AddImport(qualifiedName, model.EntityName);
if (mappings.IsAutoImport && model.EntityName.IndexOf('.') > 0)
- mappings.AddImport(model.MappedClass.AssemblyQualifiedName, StringHelper.Unqualify(model.EntityName));
+ mappings.AddImport(qualifiedName, StringHelper.Unqualify(model.EntityName));
// BATCH SIZE
XmlAttribute ...
[truncated message content] |
|
From: <fab...@us...> - 2008-07-22 18:55:10
|
Revision: 3645
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3645&view=rev
Author: fabiomaulo
Date: 2008-07-22 18:55:18 +0000 (Tue, 22 Jul 2008)
Log Message:
-----------
Fix NH-1253 (thanks to Jakob Andersen)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/IMultiQuery.cs
trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs
trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs
trunk/nhibernate/src/NHibernate/Util/StringHelper.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Car.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Mappings.hbm.xml
Modified: trunk/nhibernate/src/NHibernate/IMultiQuery.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/IMultiQuery.cs 2008-07-21 15:21:34 UTC (rev 3644)
+++ trunk/nhibernate/src/NHibernate/IMultiQuery.cs 2008-07-22 18:55:18 UTC (rev 3645)
@@ -61,9 +61,9 @@
IMultiQuery SetCacheable(bool cacheable);
/// Set the name of the cache region.
- /// <param name="cacheRegion">The name of a query cache region, or <see langword="null" />
+ /// <param name="region">The name of a query cache region, or <see langword="null" />
/// for the default query cache</param>
- IMultiQuery SetCacheRegion(string cacheRegion);
+ IMultiQuery SetCacheRegion(string region);
/// Should the query force a refresh of the specified query cache region?
/// This is particularly useful in cases where underlying data may have been
@@ -261,7 +261,7 @@
/// <summary>
/// Override the current session flush mode, just for this query.
/// </summary>
- IMultiQuery SetFlushMode(FlushMode flushMode);
+ IMultiQuery SetFlushMode(FlushMode mode);
/// <summary>
/// Set a strategy for handling the query results. This can be used to change
Modified: trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs 2008-07-21 15:21:34 UTC (rev 3644)
+++ trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs 2008-07-22 18:55:18 UTC (rev 3645)
@@ -267,12 +267,12 @@
if (i > 0)
list.Append(StringHelper.CommaSpace);
- string alias = (isJpaPositionalParam ? 'x' + name : name) + i++ + StringHelper.Underscore;
+ string alias = (isJpaPositionalParam ? 'x' + name : name + StringHelper.Underscore) + i++ + StringHelper.Underscore;
namedParamsCopy[alias] = new TypedValue(type, obj, session.EntityMode);
list.Append(ParserHelper.HqlVariablePrefix).Append(alias);
}
string paramPrefix = isJpaPositionalParam ? StringHelper.SqlParameter : ParserHelper.HqlVariablePrefix;
- return StringHelper.Replace(query, paramPrefix + name, list.ToString());
+ return StringHelper.Replace(query, paramPrefix + name, list.ToString(), true);
}
#region Parameters
Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2008-07-21 15:21:34 UTC (rev 3644)
+++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2008-07-22 18:55:18 UTC (rev 3645)
@@ -26,21 +26,21 @@
private readonly List<QueryTranslator> translators = new List<QueryTranslator>();
private readonly List<QueryParameters> parameters = new List<QueryParameters>();
private IList criteriaResults;
- private Dictionary<string, int> criteriaResultPositions = new Dictionary<string, int>();
+ private readonly Dictionary<string, int> criteriaResultPositions = new Dictionary<string, int>();
private string cacheRegion;
private int commandTimeout = RowSelection.NoValue;
- private bool isCacheable = false;
+ private bool isCacheable;
private readonly ISessionImplementor session;
private IResultTransformer resultTransformer;
private readonly List<SqlType> types = new List<SqlType>();
- private SqlString sqlString = null;
+ private SqlString sqlString;
private readonly Dialect.Dialect dialect;
private bool forceCacheRefresh;
private QueryParameters combinedParameters;
private readonly List<string> namedParametersThatAreSafeToDuplicate = new List<string>();
private FlushMode flushMode = FlushMode.Unspecified;
private FlushMode sessionFlushMode = FlushMode.Unspecified;
- private static readonly Regex parseParameterListOrignialName = new Regex(@"(.*?)\d+_", RegexOptions.Compiled);
+ private static readonly Regex parseParameterListOrignialName = new Regex(@"(?<orgname>.*?)_\d+_", RegexOptions.Compiled);
public MultiQueryImpl(ISessionImplementor session)
{
@@ -334,9 +334,9 @@
return this;
}
- public IMultiQuery SetCacheRegion(string cacheRegion)
+ public IMultiQuery SetCacheRegion(string region)
{
- this.cacheRegion = cacheRegion;
+ cacheRegion = region;
return this;
}
@@ -361,14 +361,7 @@
{
Before();
- if (cacheable)
- {
- criteriaResults = ListUsingQueryCache();
- }
- else
- {
- criteriaResults = ListIgnoreQueryCache();
- }
+ criteriaResults = cacheable ? ListUsingQueryCache() : ListIgnoreQueryCache();
return criteriaResults;
}
finally
@@ -377,9 +370,9 @@
}
}
- public IMultiQuery SetFlushMode(FlushMode flushMode)
+ public IMultiQuery SetFlushMode(FlushMode mode)
{
- this.flushMode = flushMode;
+ flushMode = mode;
return this;
}
@@ -757,7 +750,7 @@
Match match = parseParameterListOrignialName.Match(name);
if (match != null)
{
- string originalName = match.Groups[1].Value;
+ string originalName = match.Groups["orgname"].Value;
return namedParametersThatAreSafeToDuplicate.Contains(originalName);
}
return false;
Modified: trunk/nhibernate/src/NHibernate/Util/StringHelper.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Util/StringHelper.cs 2008-07-21 15:21:34 UTC (rev 3644)
+++ trunk/nhibernate/src/NHibernate/Util/StringHelper.cs 2008-07-22 18:55:18 UTC (rev 3645)
@@ -109,15 +109,13 @@
return buf.ToString();
}
- /// <summary>
- ///
- /// </summary>
- /// <param name="template"></param>
- /// <param name="placeholder"></param>
- /// <param name="replacement"></param>
- /// <returns></returns>
public static string Replace(string template, string placeholder, string replacement)
{
+ return Replace(template, placeholder, replacement, false);
+ }
+
+ public static string Replace(string template, string placeholder, string replacement, bool wholeWords)
+ {
// sometimes a null value will get passed in here -> SqlWhereStrings are a good example
if (template == null)
{
@@ -131,13 +129,22 @@
}
else
{
- return new StringBuilder(template.Substring(0, loc))
- .Append(replacement)
- .Append(Replace(
- template.Substring(loc + placeholder.Length),
- placeholder,
- replacement
- )).ToString();
+ // NH different implementation (NH-1253)
+ string replaceWith = replacement;
+ if(loc + placeholder.Length < template.Length)
+ {
+ string afterPlaceholder = template[loc + placeholder.Length].ToString();
+ //After a token in HQL there can be whitespace, closedparen or comma..
+ if(wholeWords && !(WhiteSpace.Contains(afterPlaceholder) || ClosedParen.Equals(afterPlaceholder) || Comma.Equals(afterPlaceholder)))
+ {
+ //If this is not a full token we don't want to touch it
+ replaceWith = placeholder;
+ }
+ }
+
+ return
+ new StringBuilder(template.Substring(0, loc)).Append(replaceWith).Append(
+ Replace(template.Substring(loc + placeholder.Length), placeholder, replacement, wholeWords)).ToString();
}
}
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Car.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Car.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Car.cs 2008-07-22 18:55:18 UTC (rev 3645)
@@ -0,0 +1,27 @@
+namespace NHibernate.Test.NHSpecificTest.NH1253
+{
+ public class Car
+ {
+ private int _Id;
+ private string _Make;
+ private string _Model;
+
+ public virtual int Id
+ {
+ get { return _Id; }
+ set { _Id = value; }
+ }
+
+ public virtual string Model
+ {
+ get { return _Model; }
+ set { _Model = value; }
+ }
+
+ public virtual string Make
+ {
+ get { return _Make; }
+ set { _Make = value; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Fixture.cs 2008-07-22 18:55:18 UTC (rev 3645)
@@ -0,0 +1,82 @@
+using System.Collections;
+using System.Collections.Generic;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH1253
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ // The test only check that there are no lost parameter set (no exception)
+ [Test]
+ public void TestParametersWithTrailingNumbersSingleInList()
+ {
+ using (ISession s = OpenSession())
+ {
+ using (ITransaction tx = s.BeginTransaction())
+ {
+ IQuery q = s.CreateQuery("from Car c where c.Make in (:param1) or c.Model in (:param11)");
+ q.SetParameterList("param11", new string[] { "Model1", "Model2" });
+ q.SetParameterList("param1", new string[] { "Make1", "Make2" });
+ IList<Car> cars = q.List<Car>();
+
+ tx.Commit();
+ }
+ }
+ }
+
+ [Test]
+ public void TestParametersWithTrailingNumbersSingleInListReverse()
+ {
+ using (ISession s = OpenSession())
+ {
+ using (ITransaction tx = s.BeginTransaction())
+ {
+ IQuery q = s.CreateQuery("from Car c where c.Make in (:param1) or c.Model in (:param11)");
+ q.SetParameterList("param1", new string[] { "Model1", "Model2" });
+ q.SetParameterList("param11", new string[] { "Make1", "Make2" });
+ IList<Car> cars = q.List<Car>();
+
+ tx.Commit();
+ }
+ }
+ }
+
+ [Test]
+ public void TestParametersWithTrailingNumbersMultipleInList()
+ {
+ using (ISession s = OpenSession())
+ {
+ using (ITransaction tx = s.BeginTransaction())
+ {
+ IQuery q = s.CreateQuery("from Car c where c.Make in (:param11) or c.Model in (:param1)");
+ q.SetParameterList("param11", new string[] { "One", "Two" });
+ q.SetParameterList("param1", new string[] { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve" });
+ IList cars = q.List();
+
+ tx.Commit();
+ }
+ }
+ }
+
+ [Test]
+ public void MultiQuerySingleInList()
+ {
+ using (ISession s = OpenSession())
+ {
+ using (ITransaction tx = s.BeginTransaction())
+ {
+ IList results = s.CreateMultiQuery()
+ .Add("from Car c where c.Make in (:param1) or c.Model in (:param11)")
+ .Add("from Car c where c.Make in (:param1) or c.Model in (:param11)")
+ .SetParameterList("param11",new string[]{"Model1", "Model2"})
+ .SetParameterList("param1", new string[] {"Make1", "Make2"})
+ .List();
+
+ tx.Commit();
+ }
+ }
+ }
+
+ }
+}
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Mappings.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1253/Mappings.hbm.xml 2008-07-22 18:55:18 UTC (rev 3645)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHibernate.Test.NHSpecificTest.NH1253" assembly="NHibernate.Test">
+ <class name="Car" table="Cars">
+ <id name="Id" column="CarID" type="Int32">
+ <generator class="native" />
+ </id>
+ <property name="Make" type="string" />
+ <property name="Model" type="string" />
+ </class>
+</hibernate-mapping>
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-21 15:21:34 UTC (rev 3644)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-22 18:55:18 UTC (rev 3645)
@@ -355,6 +355,8 @@
<Compile Include="NHSpecificTest\NH1230\PreSaveDoVeto.cs" />
<Compile Include="NHSpecificTest\NH1250\Model.cs" />
<Compile Include="NHSpecificTest\NH1250\PolymorphicJoinFetchFixture.cs" />
+ <Compile Include="NHSpecificTest\NH1253\Car.cs" />
+ <Compile Include="NHSpecificTest\NH1253\Fixture.cs" />
<Compile Include="NHSpecificTest\NH1275\A.cs" />
<Compile Include="NHSpecificTest\NH1275\Fixture.cs" />
<Compile Include="NHSpecificTest\NH1284\Fixture.cs" />
@@ -1361,6 +1363,7 @@
<ItemGroup>
<EmbeddedResource Include="DynamicEntity\Interceptor\Customer.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="NHSpecificTest\NH1253\Mappings.hbm.xml" />
<EmbeddedResource Include="EntityModeTest\Map\Basic\ProductLine.hbm.xml" />
<EmbeddedResource Include="DynamicEntity\Tuplizer\Customer.hbm.xml" />
</ItemGroup>
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj 2008-07-21 15:21:34 UTC (rev 3644)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj 2008-07-22 18:55:18 UTC (rev 3645)
@@ -294,6 +294,8 @@
<Compile Include="NHSpecificTest\NH1144\Fixture.cs" />
<Compile Include="NHSpecificTest\CriteriaFromHql\Person.cs" />
<Compile Include="NHSpecificTest\CriteriaFromHql\Fixture.cs" />
+ <Compile Include="NHSpecificTest\NH1253\Car.cs" />
+ <Compile Include="NHSpecificTest\NH1253\Fixture.cs" />
<Compile Include="NHSpecificTest\NH1284\Fixture.cs">
<SubType>Code</SubType>
</Compile>
@@ -1321,6 +1323,9 @@
<EmbeddedResource Include="NHSpecificTest\NH1359\Mappings.hbm.xml" />
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="NHSpecificTest\NH1253\Mappings.hbm.xml" />
+ </ItemGroup>
+ <ItemGroup>
<Folder Include="Properties\" />
<Folder Include="Unionsubclass2\" />
</ItemGroup>
@@ -1340,4 +1345,4 @@
if exist "$(ProjectDir)hibernate.cfg.xml" (copy "$(ProjectDir)hibernate.cfg.xml" "hibernate.cfg.xml")
copy /y "..\..\..\NHibernate.DomainModel\ABC.hbm.xml" "ABC.hbm.xml"</PostBuildEvent>
</PropertyGroup>
-</Project>
\ No newline at end of file
+</Project>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-07-22 19:16:43
|
Revision: 3647
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3647&view=rev
Author: fabiomaulo
Date: 2008-07-22 19:16:52 +0000 (Tue, 22 Jul 2008)
Log Message:
-----------
re-fix NH-1254 to support the two drivers
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Dialect/SybaseAnywhereDialect.cs
trunk/nhibernate/src/NHibernate/Driver/ASAClientDriver.cs
trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Driver/ASA10ClientDriver.cs
Modified: trunk/nhibernate/src/NHibernate/Dialect/SybaseAnywhereDialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/SybaseAnywhereDialect.cs 2008-07-22 19:12:25 UTC (rev 3646)
+++ trunk/nhibernate/src/NHibernate/Dialect/SybaseAnywhereDialect.cs 2008-07-22 19:16:52 UTC (rev 3647)
@@ -3,14 +3,14 @@
namespace NHibernate.Dialect
{
/// <summary>
- /// An SQL dialect for Sybase Adaptive Server Anywhere 10.0
+ /// An SQL dialect for Sybase Adaptive Server Anywhere 9.0/10.0
/// </summary>
/// <remarks>
/// <p>
/// This dialect probably will not work with schema-export. If anyone out there
/// can fill in the ctor with DbTypes to Strings that would be helpful.
/// </p>
- /// The SybaseAnywhere10Dialect defaults the following configuration properties:
+ /// The SybaseAnywhereDialect defaults the following configuration properties:
/// <list type="table">
/// <listheader>
/// <term>Property</term>
Added: trunk/nhibernate/src/NHibernate/Driver/ASA10ClientDriver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Driver/ASA10ClientDriver.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Driver/ASA10ClientDriver.cs 2008-07-22 19:16:52 UTC (rev 3647)
@@ -0,0 +1,41 @@
+namespace NHibernate.Driver
+{
+ /// <summary>
+ /// The ASAClientDriver Driver provides a database driver for Adaptive Server Anywhere 10.0.
+ /// </summary>
+ public class ASA10ClientDriver : ReflectionBasedDriver
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ASAClientDriver"/> class.
+ /// </summary>
+ /// <exception cref="HibernateException">
+ /// Thrown when the iAnywhere.Data.SQLAnywhere assembly is not and can not be loaded.
+ /// </exception>
+ public ASA10ClientDriver()
+ : base("iAnywhere.Data.SQLAnywhere", "iAnywhere.Data.SQLAnywhere.SAConnection", "iAnywhere.Data.SQLAnywhere.SACommand")
+ {
+ }
+
+ /// <summary>
+ /// iAnywhere.Data.SQLAnywhere uses named parameters in the sql.
+ /// </summary>
+ /// <value><see langword="true" /> - Sybase uses <c>String.Empty</c> in the sql.</value>
+ public override bool UseNamedPrefixInSql
+ {
+ get { return false; }
+ }
+
+ public override bool UseNamedPrefixInParameter
+ {
+ get { return false; }
+ }
+
+ /// <summary>
+ /// iAnywhere.Data.SQLAnywhere use the <c>string.Empty</c> to locate parameters in sql.
+ /// </summary>
+ public override string NamedPrefix
+ {
+ get { return string.Empty; }
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate/Driver/ASAClientDriver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Driver/ASAClientDriver.cs 2008-07-22 19:12:25 UTC (rev 3646)
+++ trunk/nhibernate/src/NHibernate/Driver/ASAClientDriver.cs 2008-07-22 19:16:52 UTC (rev 3647)
@@ -1,5 +1,3 @@
-using System;
-
namespace NHibernate.Driver
{
/// <summary>
@@ -11,15 +9,15 @@
/// Initializes a new instance of the <see cref="ASAClientDriver"/> class.
/// </summary>
/// <exception cref="HibernateException">
- /// Thrown when the iAnywhere.Data.SQLAnywhere assembly is not and can not be loaded.
+ /// Thrown when the ASA.Data.AsaClient assembly is not and can not be loaded.
/// </exception>
public ASAClientDriver()
- : base("iAnywhere.Data.SQLAnywhere", "iAnywhere.Data.SQLAnywhere.SAConnection", "iAnywhere.Data.SQLAnywhere.SACommand")
+ : base("iAnywhere.Data.AsaClient", "iAnywhere.Data.AsaClient.AsaConnection", "iAnywhere.Data.AsaClient.AsaCommand")
{
}
/// <summary>
- /// iAnywhere.Data.SQLAnywhere uses named parameters in the sql.
+ /// iAnywhere.Data.AsaClient uses named parameters in the sql.
/// </summary>
/// <value><see langword="true" /> - Sybase uses <c>String.Empty</c> in the sql.</value>
public override bool UseNamedPrefixInSql
@@ -33,7 +31,7 @@
}
/// <summary>
- /// iAnywhere.Data.SQLAnywhere use the <c>string.Empty</c> to locate parameters in sql.
+ /// iAnywhere.Data.AsaClient use the <c>string.Empty</c> to locate parameters in sql.
/// </summary>
public override string NamedPrefix
{
Modified: trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj 2008-07-22 19:12:25 UTC (rev 3646)
+++ trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj 2008-07-22 19:16:52 UTC (rev 3647)
@@ -593,6 +593,7 @@
<Compile Include="Dialect\Schema\MsSqlMetaData.cs" />
<Compile Include="Dialect\Schema\OracleMetaData.cs" />
<Compile Include="Dialect\Sybase11Dialect.cs" />
+ <Compile Include="Driver\ASA10ClientDriver.cs" />
<Compile Include="Driver\ISqlParameterFormatter.cs" />
<Compile Include="Driver\SqlStringFormatter.cs" />
<Compile Include="Criterion\SubqueryProjection.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-07-22 22:05:30
|
Revision: 3649
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3649&view=rev
Author: fabiomaulo
Date: 2008-07-22 22:05:35 +0000 (Tue, 22 Jul 2008)
Log Message:
-----------
Merge r3648 (fix NH-1399)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Mapping/Table.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1399/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1399/Fixture.cs
Modified: trunk/nhibernate/src/NHibernate/Mapping/Table.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/Table.cs 2008-07-22 21:34:20 UTC (rev 3648)
+++ trunk/nhibernate/src/NHibernate/Mapping/Table.cs 2008-07-22 22:05:35 UTC (rev 3649)
@@ -709,20 +709,14 @@
public string UniqueColumnString(IEnumerable iterator, string referencedEntityName)
{
- int result = 0;
+ // NH Different implementation (NH-1339)
+ int result = 37;
if (referencedEntityName != null)
- result += referencedEntityName.GetHashCode();
+ result ^= referencedEntityName.GetHashCode();
foreach (object o in iterator)
{
- // this is marked as unchecked because the GetHashCode could potentially
- // cause an integer overflow. This way if there is an overflow it will
- // just roll back over - since we are not doing any computations based
- // on this number then a rollover is no big deal.
- unchecked
- {
- result += o.GetHashCode();
- }
+ result ^= o.GetHashCode();
}
return (name.GetHashCode().ToString("X") + result.GetHashCode().ToString("X"));
}
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1399/Fixture.cs (from rev 3648, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1399/Fixture.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1399/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1399/Fixture.cs 2008-07-22 22:05:35 UTC (rev 3649)
@@ -0,0 +1,21 @@
+using NHibernate.Mapping;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH1399
+{
+ [TestFixture]
+ public class Fixture
+ {
+ [Test]
+ public void Bug()
+ {
+ Table table1 = new Table("ATABLE");
+
+ Column table1ITestManyA = new Column("itestmanyaid");
+ Column table1ITestManyB = new Column("itestmanybid");
+ string t1Fk = table1.UniqueColumnString(new object[] { table1ITestManyA }, "BluewireTechnologies.Core.Framework.DynamicTypes2.Albatross.ITestManyA");
+ string t2Fk = table1.UniqueColumnString(new object[] { table1ITestManyB }, "BluewireTechnologies.Core.Framework.DynamicTypes2.Albatross.ITestManyB");
+ Assert.AreNotEqual(t1Fk, t2Fk, "Different columns in differents tables create the same FK name.");
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1399/Fixture.cs
___________________________________________________________________
Added: svn:mergeinfo
+
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-22 21:34:20 UTC (rev 3648)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-22 22:05:35 UTC (rev 3649)
@@ -387,6 +387,7 @@
<Compile Include="NHSpecificTest\NH1355\Category.cs" />
<Compile Include="NHSpecificTest\NH1355\CustomVersionType.cs" />
<Compile Include="NHSpecificTest\NH1355\UserTypeTimestamp.cs" />
+ <Compile Include="NHSpecificTest\NH1399\Fixture.cs" />
<Compile Include="NHSpecificTest\NH280\Fixture.cs" />
<Compile Include="NHSpecificTest\NH280\Foo.cs" />
<Compile Include="NHSpecificTest\NH1018\Employee.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-07-23 03:36:07
|
Revision: 3653
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3653&view=rev
Author: fabiomaulo
Date: 2008-07-23 03:36:16 +0000 (Wed, 23 Jul 2008)
Log Message:
-----------
Fix NH-1361 (thanks to Carsten Hess)
Possible Breaking Change:
The ProxyTypeValidator make a more accurate check so your may not pass the validation
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Proxy/ProxyTypeValidator.cs
trunk/nhibernate/src/NHibernate.DomainModel/Qux.cs
trunk/nhibernate/src/NHibernate.Test/Classic/Video.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/ProxyValidator/Fixture.cs
Modified: trunk/nhibernate/src/NHibernate/Proxy/ProxyTypeValidator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Proxy/ProxyTypeValidator.cs 2008-07-23 03:24:41 UTC (rev 3652)
+++ trunk/nhibernate/src/NHibernate/Proxy/ProxyTypeValidator.cs 2008-07-23 03:36:16 UTC (rev 3653)
@@ -94,7 +94,7 @@
if (method.DeclaringType != typeof(object) &&
(method.IsPublic || method.IsAssembly || method.IsFamilyOrAssembly))
{
- if (!method.IsVirtual)
+ if (!method.IsVirtual || method.IsFinal)
{
Error(errors, type, "method " + method.Name + " should be virtual");
}
Modified: trunk/nhibernate/src/NHibernate.DomainModel/Qux.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.DomainModel/Qux.cs 2008-07-23 03:24:41 UTC (rev 3652)
+++ trunk/nhibernate/src/NHibernate.DomainModel/Qux.cs 2008-07-23 03:36:16 UTC (rev 3653)
@@ -36,7 +36,7 @@
#region ILifecycle members
- public LifecycleVeto OnSave(ISession session)
+ public virtual LifecycleVeto OnSave(ISession session)
{
_created = true;
try
@@ -52,7 +52,7 @@
return LifecycleVeto.NoVeto;
}
- public LifecycleVeto OnDelete(ISession session)
+ public virtual LifecycleVeto OnDelete(ISession session)
{
_deleted = true;
try
@@ -67,13 +67,13 @@
return LifecycleVeto.NoVeto;
}
- public void OnLoad(ISession session, object id)
+ public virtual void OnLoad(ISession session, object id)
{
_loaded = true;
_session = session;
}
- public LifecycleVeto OnUpdate(ISession s)
+ public virtual LifecycleVeto OnUpdate(ISession s)
{
return LifecycleVeto.NoVeto;
}
@@ -197,4 +197,4 @@
set { _holder = value; }
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate.Test/Classic/Video.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Classic/Video.cs 2008-07-23 03:24:41 UTC (rev 3652)
+++ trunk/nhibernate/src/NHibernate.Test/Classic/Video.cs 2008-07-23 03:36:16 UTC (rev 3653)
@@ -63,7 +63,7 @@
/// throw a <see cref="ValidationFailure" />. This method must not change the state of the object
/// by side-effect.
/// </summary>
- public void Validate()
+ public virtual void Validate()
{
IList<string> br = GetBrokenRules();
if (br != null && br.Count > 0)
Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/ProxyValidator/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/ProxyValidator/Fixture.cs 2008-07-23 03:24:41 UTC (rev 3652)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/ProxyValidator/Fixture.cs 2008-07-23 03:36:16 UTC (rev 3653)
@@ -227,5 +227,25 @@
{
Validate(typeof(InvalidNonVirtualProtectedInternalProperty));
}
+
+ interface INonVirtualPublicImplementsInterface
+ {
+ int NonVirtualMethodImplementsInterface { get; }
+ }
+
+ public class NonVirtualPublicImplementsInterface : ValidClass, INonVirtualPublicImplementsInterface
+ {
+ public int NonVirtualMethodImplementsInterface
+ {
+ get { return 0; }
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(InvalidProxyTypeException))]
+ public void VirtualPublicImplementsInterface()
+ {
+ Validate(typeof(NonVirtualPublicImplementsInterface));
+ }
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-07-23 16:39:20
|
Revision: 3655
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3655&view=rev
Author: fabiomaulo
Date: 2008-07-23 16:39:27 +0000 (Wed, 23 Jul 2008)
Log Message:
-----------
Merge r3654 (fix NH-1403)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs
trunk/nhibernate/src/NHibernate/Mapping/Any.cs
trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj
trunk/nhibernate/src/NHibernate/NHibernateUtil.cs
trunk/nhibernate/src/NHibernate/Type/TypeType.cs
trunk/nhibernate/src/NHibernate.DomainModel/FooBar.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Legacy/FooBarTest.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Type/ClassMetaType.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Female.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Hobby.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Male.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Person.cs
Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs 2008-07-23 15:38:48 UTC (rev 3654)
+++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -819,40 +819,33 @@
XmlAttribute metaAttribute = node.Attributes["meta-type"];
if (metaAttribute != null)
{
- IType metaType = TypeFactory.HeuristicType(metaAttribute.Value);
- if (metaType == null)
- throw new MappingException("could not interpret meta-type");
- model.MetaType = metaType.Name;
-
- IDictionary<object, string> values = new Dictionary<object, string>();
- foreach (XmlNode metaValue in node.SelectNodes(HbmConstants.nsMetaValue, namespaceManager))
- try
- {
- object value = ((IDiscriminatorType) metaType).StringToObject(metaValue.Attributes["value"].Value);
- string entityName = GetClassName(metaValue.Attributes["class"].Value, mappings);
- values[value] = entityName;
- }
- catch (InvalidCastException)
- {
- throw new MappingException("meta-type was not an IDiscriminatorType: " + metaType.Name);
- }
- catch (HibernateException he)
- {
- throw new MappingException("could not interpret meta-value", he);
- }
- catch (TypeLoadException cnfe)
- {
- throw new MappingException("meta-value class not found", cnfe);
- }
-
- if (values.Count > 0)
+ model.MetaType = metaAttribute.Value;
+ XmlNodeList metaValues = node.SelectNodes(HbmConstants.nsMetaValue, namespaceManager);
+ if (metaValues != null && metaValues.Count > 0)
{
- model.MetaValues = values;
+ IDictionary<object, string> values = new Dictionary<object, string>();
+ IType metaType = TypeFactory.HeuristicType(model.MetaType);
+ foreach (XmlNode metaValue in metaValues)
+ try
+ {
+ object value = ((IDiscriminatorType)metaType).StringToObject(metaValue.Attributes["value"].Value);
+ string entityName = GetClassName(metaValue.Attributes["class"].Value, mappings);
+ values[value] = entityName;
+ }
+ catch (InvalidCastException)
+ {
+ throw new MappingException("meta-type was not an IDiscriminatorType: " + metaType.Name);
+ }
+ catch (HibernateException he)
+ {
+ throw new MappingException("could not interpret meta-value", he);
+ }
+ catch (TypeLoadException cnfe)
+ {
+ throw new MappingException("meta-value class not found", cnfe);
+ }
+ model.MetaValues = values.Count > 0 ? values : null;
}
- else
- {
- model.MetaValues = null;
- }
}
BindColumns(node, model, isNullable, false, null);
Modified: trunk/nhibernate/src/NHibernate/Mapping/Any.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/Any.cs 2008-07-23 15:38:48 UTC (rev 3654)
+++ trunk/nhibernate/src/NHibernate/Mapping/Any.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -40,7 +40,7 @@
type =
new AnyType(
metaValues == null
- ? TypeFactory.HeuristicType(metaTypeName)
+ ? ("class".Equals(metaTypeName) ? new ClassMetaType(): TypeFactory.HeuristicType(metaTypeName))
: new MetaType(metaValues, TypeFactory.HeuristicType(metaTypeName)),
TypeFactory.HeuristicType(identifierTypeName));
}
@@ -70,4 +70,4 @@
set { metaValues = value; }
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj 2008-07-23 15:38:48 UTC (rev 3654)
+++ trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj 2008-07-23 16:39:27 UTC (rev 3655)
@@ -1028,6 +1028,7 @@
<Compile Include="Type\AnsiCharType.cs" />
<Compile Include="Type\AnyType.cs" />
<Compile Include="Type\AbstractCharType.cs" />
+ <Compile Include="Type\ClassMetaType.cs" />
<Compile Include="Type\CollectionType.cs" />
<Compile Include="Type\CustomCollectionType.cs" />
<Compile Include="Type\EmbeddedComponentType.cs" />
Modified: trunk/nhibernate/src/NHibernate/NHibernateUtil.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernateUtil.cs 2008-07-23 15:38:48 UTC (rev 3654)
+++ trunk/nhibernate/src/NHibernate/NHibernateUtil.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -221,6 +221,12 @@
public static readonly NullableType Class = new TypeType();
/// <summary>
+ /// NHibernate class meta type for associtiation of kind <code>any</code>.
+ /// </summary>
+ /// <seealso cref="AnyType"/>
+ public static readonly IType ClassMetaType = new ClassMetaType();
+
+ /// <summary>
/// NHibernate serializable type
/// </summary>
public static readonly NullableType Serializable = new SerializableType();
@@ -526,4 +532,4 @@
}
}
}
-}
\ No newline at end of file
+}
Added: trunk/nhibernate/src/NHibernate/Type/ClassMetaType.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Type/ClassMetaType.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Type/ClassMetaType.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -0,0 +1,125 @@
+using System;
+using System.Data;
+using System.Xml;
+using NHibernate.Engine;
+using NHibernate.SqlTypes;
+
+namespace NHibernate.Type
+{
+ /// <summary>
+ /// ClassMetaType is a NH specif type to support "any" with meta-type="class"
+ /// </summary>
+ /// <remarks>
+ /// It work like a MetaType where the key is the entity-name it self
+ /// </remarks>
+ [Serializable]
+ public class ClassMetaType : AbstractType
+ {
+ public override SqlType[] SqlTypes(IMapping mapping)
+ {
+ return new SqlType[] { NHibernateUtil.String.SqlType };
+ }
+
+ public override int GetColumnSpan(IMapping mapping)
+ {
+ return 1;
+ }
+
+ public override System.Type ReturnedClass
+ {
+ get { return typeof (string); }
+ }
+
+ public override object NullSafeGet(IDataReader rs, string[] names, ISessionImplementor session, object owner)
+ {
+ return NullSafeGet(rs, names[0], session, owner);
+ }
+
+ public override object NullSafeGet(IDataReader rs,string name,ISessionImplementor session,object owner)
+ {
+ int index = rs.GetOrdinal(name);
+
+ if (rs.IsDBNull(index))
+ {
+ return null;
+ }
+ else
+ {
+ string str = (string) NHibernateUtil.String.Get(rs, index);
+ return string.IsNullOrEmpty(str) ? null : str;
+ }
+ }
+
+ public override void NullSafeSet(IDbCommand st, object value, int index, bool[] settable, ISessionImplementor session)
+ {
+ if (settable[0]) NullSafeSet(st, value, index, session);
+ }
+
+ public override void NullSafeSet(IDbCommand st,object value,int index,ISessionImplementor session)
+ {
+ if (value == null)
+ {
+ ((IDataParameter)st.Parameters[index]).Value = DBNull.Value;
+ }
+ else
+ {
+ NHibernateUtil.String.Set(st, value, index);
+ }
+ }
+
+ public override string ToLoggableString(object value, ISessionFactoryImplementor factory)
+ {
+ return ToXMLString(value, factory);
+ }
+
+ public override string Name
+ {
+ get { return "ClassMetaType"; }
+ }
+
+ public override object DeepCopy(object value, EntityMode entityMode, ISessionFactoryImplementor factory)
+ {
+ return value;
+ }
+
+ public override bool IsMutable
+ {
+ get { return false; }
+ }
+
+ public override bool IsDirty(object old, object current, bool[] checkable, ISessionImplementor session)
+ {
+ return checkable[0] && IsDirty(old, current, session);
+ }
+
+ public override object FromXMLNode(XmlNode xml, IMapping factory)
+ {
+ return FromXMLString(xml.Value, factory);
+ }
+
+ public object FromXMLString(string xml, IMapping factory)
+ {
+ return xml; //xml is the entity name
+ }
+
+ public override object Replace(object original, object current, ISessionImplementor session, object owner, System.Collections.IDictionary copiedAlready)
+ {
+ return original;
+ }
+
+ public override void SetToXMLNode(XmlNode node, object value, ISessionFactoryImplementor factory)
+ {
+ node.Value = ToXMLString(value, factory);
+ }
+
+ public override bool[] ToColumnNullness(object value, IMapping mapping)
+ {
+ throw new NotSupportedException();
+ }
+
+ public string ToXMLString(object value, ISessionFactoryImplementor factory)
+ {
+ return (string)value; //value is the entity name
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate/Type/TypeType.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Type/TypeType.cs 2008-07-23 15:38:48 UTC (rev 3654)
+++ trunk/nhibernate/src/NHibernate/Type/TypeType.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -90,7 +90,7 @@
/// </remarks>
public override void Set(IDbCommand cmd, object value, int index)
{
- NHibernateUtil.String.Set(cmd, ((System.Type)value).FullName, index);
+ NHibernateUtil.String.Set(cmd, ((System.Type)value).AssemblyQualifiedName, index);
}
/// <summary>
@@ -101,7 +101,7 @@
/// <returns>An Xml formatted string that contains the Assembly Qualified Name.</returns>
public override string ToString(object value)
{
- return ((System.Type)value).FullName;
+ return ((System.Type)value).AssemblyQualifiedName;
}
/// <summary>
@@ -134,4 +134,4 @@
}
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate.DomainModel/FooBar.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.DomainModel/FooBar.hbm.xml 2008-07-23 15:38:48 UTC (rev 3654)
+++ trunk/nhibernate/src/NHibernate.DomainModel/FooBar.hbm.xml 2008-07-23 16:39:27 UTC (rev 3655)
@@ -197,7 +197,7 @@
<element column="date_" type="DateTime"/>
</array>
</component>
- <any name="Object" id-type="Int64" cascade="all">
+ <any name="Object" meta-type="class" id-type="Int64" cascade="all">
<!--
made clazz 200 instead of 100 because of all the extra info stored
such as assembly, key, culture
Modified: trunk/nhibernate/src/NHibernate.Test/Legacy/FooBarTest.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Legacy/FooBarTest.cs 2008-07-23 15:38:48 UTC (rev 3654)
+++ trunk/nhibernate/src/NHibernate.Test/Legacy/FooBarTest.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -5129,7 +5129,7 @@
s = OpenSession();
IList list = s.CreateQuery("from Bar bar where bar.Object.id = ? and bar.Object.class = ?")
- .SetParameter(0, oid, NHibernateUtil.Int64).SetParameter(1, typeof(One), NHibernateUtil.Class).List();
+ .SetParameter(0, oid, NHibernateUtil.Int64).SetParameter(1, typeof(One).FullName, NHibernateUtil.ClassMetaType).List();
Assert.AreEqual(1, list.Count);
// this is a little different from h2.0.3 because the full type is stored, not
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Female.cs (from rev 3654, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Female.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Female.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Female.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -0,0 +1,9 @@
+namespace NHibernate.Test.NHSpecificTest.NH1403
+{
+ public class Female : Person
+ {
+ public Female() {}
+
+ public Female(string name) : base(name) {}
+ }
+}
\ No newline at end of file
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Fixture.cs (from rev 3654, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Fixture.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Fixture.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -0,0 +1,40 @@
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH1403
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ [Test]
+ public void Bug()
+ {
+ Hobby h = new Hobby("Develop software");
+ Person p = new Male("Diego");
+ h.Person = p;
+ Hobby h1 = new Hobby("Drive Car");
+ Person p1 = new Female("Luciana");
+ h1.Person = p1;
+ object savedIdMale;
+ object saveIdFemale;
+ using (ISession s = OpenSession())
+ using(ITransaction t = s.BeginTransaction())
+ {
+ savedIdMale = s.Save(h);
+ saveIdFemale = s.Save(h1);
+ t.Commit();
+ }
+
+ using (ISession s = OpenSession())
+ using (ITransaction t = s.BeginTransaction())
+ {
+ h = s.Get<Hobby>(savedIdMale);
+ h1 = s.Get<Hobby>(saveIdFemale);
+ Assert.IsTrue(h.Person is Male);
+ Assert.IsTrue(h1.Person is Female);
+ s.Delete(h);
+ s.Delete(h1);
+ t.Commit();
+ }
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Fixture.cs
___________________________________________________________________
Added: svn:mergeinfo
+
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Hobby.cs (from rev 3654, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Hobby.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Hobby.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Hobby.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -0,0 +1,34 @@
+namespace NHibernate.Test.NHSpecificTest.NH1403
+{
+ public class Hobby
+ {
+ private int id;
+ private string name;
+ private Person person;
+
+ public Hobby() {}
+
+ public Hobby(string name) : this()
+ {
+ this.name = name;
+ }
+
+ public virtual int Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual Person Person
+ {
+ get { return person; }
+ set { person = value; }
+ }
+ }
+}
\ No newline at end of file
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Male.cs (from rev 3654, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Male.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Male.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Male.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -0,0 +1,9 @@
+namespace NHibernate.Test.NHSpecificTest.NH1403
+{
+ public class Male : Person
+ {
+ public Male() {}
+
+ public Male(string name) : base(name) {}
+ }
+}
\ No newline at end of file
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Mappings.hbm.xml (from rev 3654, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Mappings.hbm.xml)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Mappings.hbm.xml 2008-07-23 16:39:27 UTC (rev 3655)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.NHSpecificTest.NH1403">
+
+ <class name="Person">
+ <id name="Id">
+ <generator class="native" />
+ </id>
+
+ <discriminator column="Gender" type="String" />
+
+ <property name="Name" />
+
+ <subclass name="Female" discriminator-value="Female">
+ </subclass>
+
+ <subclass name="Male" discriminator-value="Male">
+ </subclass>
+ </class>
+
+ <class name="Hobby">
+ <id name="Id">
+ <generator class="native" />
+ </id>
+
+ <property name="Name" />
+ <any name="Person" meta-type="class" id-type="int" cascade="all">
+ <column name="ORIGINAL_CLASS"/>
+ <column name="ORIGINAL_ID"/>
+ </any>
+ </class>
+</hibernate-mapping>
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Person.cs (from rev 3654, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Person.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Person.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1403/Person.cs 2008-07-23 16:39:27 UTC (rev 3655)
@@ -0,0 +1,27 @@
+namespace NHibernate.Test.NHSpecificTest.NH1403
+{
+ public class Person
+ {
+ private int id;
+ private string name;
+
+ public Person() {}
+
+ public Person(string name) : this()
+ {
+ this.name = name;
+ }
+
+ public virtual int Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-23 15:38:48 UTC (rev 3654)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-23 16:39:27 UTC (rev 3655)
@@ -388,6 +388,11 @@
<Compile Include="NHSpecificTest\NH1355\CustomVersionType.cs" />
<Compile Include="NHSpecificTest\NH1355\UserTypeTimestamp.cs" />
<Compile Include="NHSpecificTest\NH1399\Fixture.cs" />
+ <Compile Include="NHSpecificTest\NH1403\Female.cs" />
+ <Compile Include="NHSpecificTest\NH1403\Fixture.cs" />
+ <Compile Include="NHSpecificTest\NH1403\Hobby.cs" />
+ <Compile Include="NHSpecificTest\NH1403\Male.cs" />
+ <Compile Include="NHSpecificTest\NH1403\Person.cs" />
<Compile Include="NHSpecificTest\NH280\Fixture.cs" />
<Compile Include="NHSpecificTest\NH280\Foo.cs" />
<Compile Include="NHSpecificTest\NH1018\Employee.cs" />
@@ -1364,6 +1369,7 @@
<ItemGroup>
<EmbeddedResource Include="DynamicEntity\Interceptor\Customer.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="NHSpecificTest\NH1403\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1253\Mappings.hbm.xml" />
<EmbeddedResource Include="EntityModeTest\Map\Basic\ProductLine.hbm.xml" />
<EmbeddedResource Include="DynamicEntity\Tuplizer\Customer.hbm.xml" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-07-25 04:52:46
|
Revision: 3661
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3661&view=rev
Author: fabiomaulo
Date: 2008-07-25 04:52:55 +0000 (Fri, 25 Jul 2008)
Log Message:
-----------
Fix NH-1405 in a different way than 2.0 branch
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Type/EmbeddedComponentType.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Column.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Mappings.hbm.xml
Modified: trunk/nhibernate/src/NHibernate/Type/EmbeddedComponentType.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Type/EmbeddedComponentType.cs 2008-07-23 23:19:37 UTC (rev 3660)
+++ trunk/nhibernate/src/NHibernate/Type/EmbeddedComponentType.cs 2008-07-25 04:52:55 UTC (rev 3661)
@@ -19,7 +19,9 @@
public override object Instantiate(object parent, ISessionImplementor session)
{
- bool useParent = parent != null && base.ReturnedClass.IsInstanceOfType(parent);
+ bool useParent= false;
+ // NH Different implemetation : since we are not sure about why H3.2 use the "parent"
+ //useParent = parent != null && base.ReturnedClass.IsInstanceOfType(parent);
return useParent ? parent : base.Instantiate(parent, session);
}
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Column.cs (from rev 3659, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Column.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Column.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Column.cs 2008-07-25 04:52:55 UTC (rev 3661)
@@ -0,0 +1,124 @@
+using System;
+
+namespace NHibernate.Test.NHSpecificTest.NH1405
+{
+ public class Column
+ {
+ /// <summary>
+ /// The column name. Part 3 of 3 of the primary key.
+ /// </summary>
+ private String _columnName;
+
+ /// <summary>
+ /// Another column in the same table.
+ /// </summary>
+ private Column _controlColumn;
+
+ /// <summary>
+ /// The system ID. Part 1 of 3 of the primary key.
+ /// </summary>
+ private String _systemId;
+
+ /// <summary>
+ /// The table name. Part 2 of 3 of the primary key.
+ /// </summary>
+ private String _tableName;
+
+ /// <summary>
+ /// The column name. Part 3 of 3 of the primary key.
+ /// </summary>
+ public virtual String ColumnName
+ {
+ get { return _columnName; }
+ set { _columnName = value; }
+ }
+
+ /// <summary>
+ /// Another column in the same table.
+ /// </summary>
+ public virtual Column ControlColumn
+ {
+ get { return _controlColumn; }
+ set { _controlColumn = value; }
+ }
+
+ /// <summary>
+ /// The system ID. Part 1 of 3 of the primary key.
+ /// </summary>
+ public virtual String SystemId
+ {
+ get { return _systemId; }
+ set { _systemId = value; }
+ }
+
+ /// <summary>
+ /// The table name. Part 2 of 3 of the primary key.
+ /// </summary>
+ public virtual String TableName
+ {
+ get { return _tableName; }
+ set { _tableName = value; }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (obj == null)
+ {
+ return false;
+ }
+ if (GetType() != obj.GetType())
+ {
+ return false;
+ }
+ Column other = (Column) obj;
+ if (null == _systemId)
+ {
+ if (null != other._systemId)
+ {
+ return false;
+ }
+ }
+ else if (!_systemId.Equals(other._systemId))
+ {
+ return false;
+ }
+ if (null == _tableName)
+ {
+ if (null != other._tableName)
+ {
+ return false;
+ }
+ }
+ else if (!_tableName.Equals(other._tableName))
+ {
+ return false;
+ }
+ if (null == _columnName)
+ {
+ if (null != other._columnName)
+ {
+ return false;
+ }
+ }
+ else if (!_columnName.Equals(other._columnName))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public override int GetHashCode()
+ {
+ const int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((null == _systemId) ? 0 : _systemId.GetHashCode());
+ result = PRIME * result + ((null == _tableName) ? 0 : _tableName.GetHashCode());
+ result = PRIME * result + ((null == _columnName) ? 0 : _columnName.GetHashCode());
+ return result;
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Column.cs
___________________________________________________________________
Added: svn:mergeinfo
+
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Fixture.cs (from rev 3660, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Fixture.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Fixture.cs 2008-07-25 04:52:55 UTC (rev 3661)
@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using System.Data;
+using NUnit.Framework;
+namespace NHibernate.Test.NHSpecificTest.NH1405
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ [Test]
+ public void Bug()
+ {
+ string[] populate = new string[]
+ {
+ "insert into PPDM_COLUMN ( SYSTEM_ID, TABLE_NAME, COLUMN_NAME, CONTROL_COLUMN ) values ( 'SYSTEM', 'TABLE', 'COLUMN1', null )",
+ "insert into PPDM_COLUMN ( SYSTEM_ID, TABLE_NAME, COLUMN_NAME, CONTROL_COLUMN ) values ( 'SYSTEM', 'TABLE', 'COLUMN2', 'COLUMN1' )",
+ "insert into PPDM_COLUMN ( SYSTEM_ID, TABLE_NAME, COLUMN_NAME, CONTROL_COLUMN ) values ( 'SYSTEM', 'TABLE', 'COLUMN3', 'COLUMN2' )"
+ };
+
+ using (ISession session = OpenSession())
+ using (ITransaction tx = session.BeginTransaction())
+ {
+ foreach (string sql in populate)
+ {
+ IDbCommand cmd = session.Connection.CreateCommand();
+ cmd.CommandText = sql;
+ tx.Enlist(cmd);
+ cmd.ExecuteNonQuery();
+ }
+ tx.Commit();
+ }
+
+ using (ISession session = OpenSession())
+ using (ITransaction tx = session.BeginTransaction())
+ {
+ IQuery query = session.CreateQuery("from Column");
+ IList<Column> columns = query.List<Column>();
+ Assert.AreEqual(3, columns.Count);
+ foreach (Column column in columns)
+ {
+ Assert.IsNotNull(column.ColumnName, "Column.ColumnName should not be null.");
+ Assert.IsFalse((null != column.ControlColumn) && (null == column.ControlColumn.ColumnName),
+ "Column's control column's ColumnName should not be null.");
+ }
+ tx.Commit();
+ }
+
+ using (ISession session = OpenSession())
+ using (ITransaction tx = session.BeginTransaction())
+ {
+ IDbCommand cmd = session.Connection.CreateCommand();
+ cmd.CommandText = "DELETE FROM PPDM_COLUMN";
+ tx.Enlist(cmd);
+ cmd.ExecuteNonQuery();
+ tx.Commit();
+ }
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Fixture.cs
___________________________________________________________________
Added: svn:mergeinfo
+
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Mappings.hbm.xml (from rev 3659, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Mappings.hbm.xml)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Mappings.hbm.xml 2008-07-25 04:52:55 UTC (rev 3661)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.NHSpecificTest.NH1405"
+ default-lazy="false">
+
+ <class name="Column" table="PPDM_COLUMN">
+ <composite-id>
+ <key-property name="SystemId" type="String" column="SYSTEM_ID" length="20" />
+ <key-property name="TableName" type="String" column="TABLE_NAME" length="30" />
+ <key-property name="ColumnName" type="String" column="COLUMN_NAME" length="30" />
+ </composite-id>
+ <!--
+ Remove this many-to-one mapping and ColumnName will be retrieved correctly -
+ keep it and ColumnName will be null.
+ ControlColumn is never fetched correctly.
+ -->
+ <many-to-one name="ControlColumn" class="Column" update="false" insert="false" not-found="ignore">
+ <column name="SYSTEM_ID" />
+ <column name="TABLE_NAME" />
+ <column name="CONTROL_COLUMN" length="30" />
+ </many-to-one>
+ </class>
+</hibernate-mapping>
+
\ No newline at end of file
Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1405/Mappings.hbm.xml
___________________________________________________________________
Added: svn:mergeinfo
+
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-23 23:19:37 UTC (rev 3660)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-25 04:52:55 UTC (rev 3661)
@@ -401,6 +401,8 @@
<Compile Include="NHSpecificTest\NH1403\Hobby.cs" />
<Compile Include="NHSpecificTest\NH1403\Male.cs" />
<Compile Include="NHSpecificTest\NH1403\Person.cs" />
+ <Compile Include="NHSpecificTest\NH1405\Column.cs" />
+ <Compile Include="NHSpecificTest\NH1405\Fixture.cs" />
<Compile Include="NHSpecificTest\NH280\Fixture.cs" />
<Compile Include="NHSpecificTest\NH280\Foo.cs" />
<Compile Include="NHSpecificTest\NH1018\Employee.cs" />
@@ -1379,6 +1381,7 @@
<EmbeddedResource Include="Any\Person.hbm.xml" />
<EmbeddedResource Include="Any\Properties.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="NHSpecificTest\NH1405\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1403\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1253\Mappings.hbm.xml" />
<EmbeddedResource Include="EntityModeTest\Map\Basic\ProductLine.hbm.xml" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-07-25 05:09:13
|
Revision: 3662
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3662&view=rev
Author: fabiomaulo
Date: 2008-07-25 05:09:20 +0000 (Fri, 25 Jul 2008)
Log Message:
-----------
Fix NH-1393 and NH-1394 (by Tuna Toksoz)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/AggregateProjection.cs
trunk/nhibernate/src/NHibernate/Criterion/AvgProjection.cs
trunk/nhibernate/src/NHibernate/Criterion/CountProjection.cs
trunk/nhibernate/src/NHibernate/Criterion/Order.cs
trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
trunk/nhibernate/src/NHibernate.Test/ExpressionTest/Projection/ProjectionFixture.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Person.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Person.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/AggregateProjection.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/AggregateProjection.cs 2008-07-25 04:52:55 UTC (rev 3661)
+++ trunk/nhibernate/src/NHibernate/Criterion/AggregateProjection.cs 2008-07-25 05:09:20 UTC (rev 3662)
@@ -1,26 +1,33 @@
using System;
+using System.Collections.Generic;
using NHibernate.SqlCommand;
using NHibernate.Type;
+using NHibernate.Util;
namespace NHibernate.Criterion
{
- using System.Collections.Generic;
-
/// <summary>
/// An Aggregation
/// </summary>
[Serializable]
public class AggregateProjection : SimpleProjection
{
+ protected readonly string aggregate;
+ protected readonly IProjection projection;
protected readonly string propertyName;
- protected readonly string aggregate;
protected internal AggregateProjection(string aggregate, string propertyName)
{
+ this.propertyName = propertyName;
this.aggregate = aggregate;
- this.propertyName = propertyName;
}
+ protected internal AggregateProjection(string aggregate, IProjection projection)
+ {
+ this.aggregate = aggregate;
+ this.projection = projection;
+ }
+
public override bool IsAggregate
{
get { return true; }
@@ -28,25 +35,38 @@
public override string ToString()
{
- return aggregate + "(" + propertyName + ')';
+ return aggregate + "(" + (projection != null ? projection.ToString() : propertyName) + ')';
}
public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
+ if (projection != null)
+ {
+ return projection.GetTypes(criteria, criteriaQuery);
+ }
return new IType[] {criteriaQuery.GetType(criteria, propertyName)};
}
- public override SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
+ public override SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery,
+ IDictionary<string, IFilter> enabledFilters)
{
- return new SqlString(new object[]
- {
- aggregate,
- "(",
- criteriaQuery.GetColumn(criteria, propertyName),
- ") as y",
- loc.ToString(),
- "_"
- });
+ if (projection != null)
+ {
+ return
+ new SqlString(new object[]
+ {
+ aggregate, "(",
+ StringHelper.RemoveAsAliasesFromSql(projection.ToSqlString(criteria, loc, criteriaQuery,
+ enabledFilters)).ToString(), ") as y",
+ loc.ToString(), "_"
+ });
+ }
+ else
+ {
+ return
+ new SqlString(new object[]
+ {aggregate, "(", criteriaQuery.GetColumn(criteria, propertyName), ") as y", loc.ToString(), "_"});
+ }
}
public override bool IsGrouped
@@ -60,4 +80,4 @@
throw new InvalidOperationException("not a grouping projection");
}
}
-}
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Criterion/AvgProjection.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/AvgProjection.cs 2008-07-25 04:52:55 UTC (rev 3661)
+++ trunk/nhibernate/src/NHibernate/Criterion/AvgProjection.cs 2008-07-25 05:09:20 UTC (rev 3662)
@@ -1,14 +1,38 @@
using System;
+using System.Collections.Generic;
+using NHibernate.Engine;
+using NHibernate.SqlCommand;
+using NHibernate.SqlTypes;
using NHibernate.Type;
+using NHibernate.Util;
namespace NHibernate.Criterion
{
[Serializable]
public class AvgProjection : AggregateProjection
{
- public AvgProjection(String propertyName)
- : base("avg", propertyName)
+ public AvgProjection(IProjection projection) : base("avg", projection) {}
+ public AvgProjection(String propertyName) : base("avg", propertyName) {}
+
+ public override SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery,
+ IDictionary<string, IFilter> enabledFilters)
{
+ ISessionFactoryImplementor factory = criteriaQuery.Factory;
+ SqlType[] sqlTypeCodes = NHibernateUtil.Double.SqlTypes(factory);
+ string sqlType = factory.Dialect.GetCastTypeName(sqlTypeCodes[0]);
+ string parameter;
+ if (projection != null)
+ {
+ parameter =
+ StringHelper.RemoveAsAliasesFromSql(projection.ToSqlString(criteria, loc, criteriaQuery, enabledFilters)).ToString();
+ }
+ else
+ {
+ parameter = criteriaQuery.GetColumn(criteria, propertyName);
+ }
+ string expression = string.Format("{0}(cast({1} as {2})) as {3}", aggregate, parameter, sqlType,
+ GetColumnAliases(loc)[0]);
+ return new SqlString(expression);
}
public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
Modified: trunk/nhibernate/src/NHibernate/Criterion/CountProjection.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/CountProjection.cs 2008-07-25 04:52:55 UTC (rev 3661)
+++ trunk/nhibernate/src/NHibernate/Criterion/CountProjection.cs 2008-07-25 05:09:20 UTC (rev 3662)
@@ -1,11 +1,10 @@
using System;
+using System.Collections.Generic;
using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Criterion
{
- using System.Collections.Generic;
-
/// <summary>
/// A Count
/// </summary>
@@ -14,10 +13,8 @@
{
private bool distinct;
- protected internal CountProjection(String prop)
- : base("count", prop)
- {
- }
+ protected internal CountProjection(String prop) : base("count", prop) {}
+ protected internal CountProjection(IProjection projection) : base("count", projection) {}
public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
@@ -29,18 +26,15 @@
return (distinct) ? "distinct " + base.ToString() : base.ToString();
}
- public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
+ public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery,
+ IDictionary<string, IFilter> enabledFilters)
{
- SqlStringBuilder buf = new SqlStringBuilder()
- .Add("count(");
+ SqlStringBuilder buf = new SqlStringBuilder().Add("count(");
if (distinct)
{
buf.Add("distinct ");
}
- buf.Add(criteriaQuery.GetColumn(criteria, propertyName))
- .Add(") as y")
- .Add(position.ToString())
- .Add("_");
+ buf.Add(criteriaQuery.GetColumn(criteria, propertyName)).Add(") as y").Add(position.ToString()).Add("_");
return buf.ToSqlString();
}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Order.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Order.cs 2008-07-25 04:52:55 UTC (rev 3661)
+++ trunk/nhibernate/src/NHibernate/Criterion/Order.cs 2008-07-25 05:09:20 UTC (rev 3662)
@@ -1,6 +1,9 @@
using System;
+using System.Collections.Generic;
using System.Text;
using NHibernate.Engine;
+using NHibernate.Criterion;
+using NHibernate.SqlCommand;
namespace NHibernate.Criterion
{
@@ -13,6 +16,17 @@
{
protected bool ascending;
protected string propertyName;
+ protected IProjection projection;
+ /// <summary>
+ /// Constructor for Order.
+ /// </summary>
+ /// <param name="projection"></param>
+ /// <param name="ascending"></param>
+ public Order(IProjection projection, bool ascending)
+ {
+ this.projection = projection;
+ this.ascending = ascending;
+ }
/// <summary>
/// Constructor for Order.
@@ -31,6 +45,16 @@
/// </summary>
public virtual string ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
+ if(projection!=null)
+ {
+ SqlString sb=new SqlString();
+ SqlString produced = this.projection.ToSqlString(criteria, 0, criteriaQuery, new Dictionary<string, IFilter>());
+ SqlString truncated = NHibernate.Util.StringHelper.RemoveAsAliasesFromSql(produced);
+ sb = sb.Append(truncated);
+ sb = sb.Append(ascending ? " asc" : " desc");
+ return sb.ToString();
+ }
+
string[] columns = criteriaQuery.GetColumnAliasesUsingProjection(criteria, propertyName);
StringBuilder fragment = new StringBuilder();
@@ -65,7 +89,7 @@
public override string ToString()
{
- return propertyName + (ascending ? " asc" : " desc");
+ return (projection!=null?projection.ToString():propertyName) + (ascending ? " asc" : " desc");
}
/// <summary>
@@ -79,8 +103,28 @@
}
/// <summary>
+ /// Ascending order
+ /// </summary>
+ /// <param name="projection"></param>
+ /// <returns></returns>
+ public static Order Asc(IProjection projection)
+ {
+ return new Order(projection, true);
+ }
+
+ /// <summary>
/// Descending order
/// </summary>
+ /// <param name="projection"></param>
+ /// <returns></returns>
+ public static Order Desc(IProjection projection)
+ {
+ return new Order(projection, false);
+ }
+
+ /// <summary>
+ /// Descending order
+ /// </summary>
/// <param name="propertyName"></param>
/// <returns></returns>
public static Order Desc(string propertyName)
@@ -88,4 +132,4 @@
return new Order(propertyName, false);
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2008-07-25 04:52:55 UTC (rev 3661)
+++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2008-07-25 05:09:20 UTC (rev 3662)
@@ -56,10 +56,18 @@
{
return new RowCountInt64Projection();
}
-
/// <summary>
/// A property value count
/// </summary>
+ /// <param name="projection"></param>
+ /// <returns></returns>
+ public static CountProjection Count(IProjection projection)
+ {
+ return new CountProjection(projection);
+ }
+ /// <summary>
+ /// A property value count
+ /// </summary>
/// <param name="propertyName"></param>
/// <returns></returns>
public static CountProjection Count(string propertyName)
@@ -88,6 +96,17 @@
}
/// <summary>
+ /// A projection maximum value
+ /// </summary>
+ /// <param name="projection"></param>
+ /// <returns></returns>
+ public static AggregateProjection Max(IProjection projection)
+ {
+ return new AggregateProjection("max", projection);
+ }
+
+
+ /// <summary>
/// A property minimum value
/// </summary>
/// <param name="propertyName"></param>
@@ -98,6 +117,16 @@
}
/// <summary>
+ /// A projection minimum value
+ /// </summary>
+ /// <param name="projection"></param>
+ /// <returns></returns>
+ public static AggregateProjection Min(IProjection projection)
+ {
+ return new AggregateProjection("min", projection);
+ }
+
+ /// <summary>
/// A property average value
/// </summary>
/// <param name="propertyName"></param>
@@ -108,6 +137,16 @@
}
/// <summary>
+ /// A property average value
+ /// </summary>
+ /// <param name="projection"></param>
+ /// <returns></returns>
+ public static AggregateProjection Avg(IProjection projection)
+ {
+ return new AvgProjection(projection);
+ }
+
+ /// <summary>
/// A property value sum
/// </summary>
/// <param name="propertyName"></param>
@@ -118,6 +157,16 @@
}
/// <summary>
+ /// A property value sum
+ /// </summary>
+ /// <param name="projection"></param>
+ /// <returns></returns>
+ public static AggregateProjection Sum(IProjection projection)
+ {
+ return new AggregateProjection("sum", projection);
+ }
+
+ /// <summary>
/// A SQL projection, a typed select clause fragment
/// </summary>
/// <param name="sql"></param>
Modified: trunk/nhibernate/src/NHibernate.Test/ExpressionTest/Projection/ProjectionFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/ExpressionTest/Projection/ProjectionFixture.cs 2008-07-25 04:52:55 UTC (rev 3661)
+++ trunk/nhibernate/src/NHibernate.Test/ExpressionTest/Projection/ProjectionFixture.cs 2008-07-25 05:09:20 UTC (rev 3662)
@@ -1,6 +1,7 @@
using NHibernate.DomainModel;
using NHibernate.Criterion;
using NHibernate.SqlCommand;
+using NHibernate.SqlTypes;
using NHibernate.Type;
using NUnit.Framework;
@@ -29,8 +30,11 @@
ISession session = factory.OpenSession();
IProjection expression = Projections.Avg("Pay");
CreateObjects(typeof(Simple), session);
+ IType nhType = NHibernateUtil.GuessType(typeof (double));
+ SqlType[] sqlTypes = nhType.SqlTypes(this.factoryImpl);
+ string sqlTypeString = factoryImpl.Dialect.GetCastTypeName(sqlTypes[0]);
SqlString sqlString = expression.ToSqlString(criteria, 0, criteriaQuery, new CollectionHelper.EmptyMapClass<string, IFilter>());
- string expectedSql = "avg(sql_alias.Pay) as y0_";
+ string expectedSql = string.Format("avg(cast(sql_alias.Pay as {0})) as y0_",sqlTypeString);
CompareSqlStrings(sqlString, expectedSql, 0);
session.Close();
}
@@ -175,4 +179,4 @@
session.Close();
}
}
-}
\ No newline at end of file
+}
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Fixture.cs 2008-07-25 05:09:20 UTC (rev 3662)
@@ -0,0 +1,105 @@
+using System.Collections;
+using NHibernate.Criterion;
+using NHibernate.Dialect.Function;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH1393
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ protected override void OnTearDown()
+ {
+ base.OnTearDown();
+ using (ISession session = OpenSession())
+ {
+ using (ITransaction tx = session.BeginTransaction())
+ {
+ session.Delete("from Person");
+ tx.Commit();
+ }
+ }
+ }
+
+ protected override void OnSetUp()
+ {
+ using (ISession s = OpenSession())
+ {
+ using (ITransaction tx = s.BeginTransaction())
+ {
+ Person e1 = new Person("Joe", 10, 9);
+ Person e2 = new Person("Sally", 100, 8);
+ Person e3 = new Person("Tim", 20, 7); //20
+ Person e4 = new Person("Fred", 40, 40);
+ Person e5 = new Person("Mike", 50, 50);
+ s.Save(e1);
+ s.Save(e2);
+ s.Save(e3);
+ s.Save(e4);
+ s.Save(e5);
+ tx.Commit();
+ }
+ }
+ }
+
+ [Test]
+ public void CanSumProjectionOnSqlFunction()
+ {
+ using (ISession s = OpenSession())
+ {
+ ISQLFunction arithmaticAddition = new VarArgsSQLFunction("(", "+", ")");
+ ICriteria c =
+ s.CreateCriteria(typeof (Person)).SetProjection(
+ Projections.Sum(Projections.SqlFunction(arithmaticAddition, NHibernateUtil.GuessType(typeof (double)),
+ Projections.Property("IQ"), Projections.Property("ShoeSize"))));
+ IList list = c.List();
+ Assert.AreEqual(334, list[0]);
+ }
+ }
+
+ [Test]
+ public void CanAvgProjectionOnSqlFunction()
+ {
+ using (ISession s = OpenSession())
+ {
+ ISQLFunction arithmaticAddition = new VarArgsSQLFunction("(", "+", ")");
+ ICriteria c =
+ s.CreateCriteria(typeof (Person)).SetProjection(
+ Projections.Avg(Projections.SqlFunction(arithmaticAddition, NHibernateUtil.GuessType(typeof (double)),
+ Projections.Property("IQ"), Projections.Property("ShoeSize"))));
+ IList list = c.List();
+ Assert.AreEqual(((double) 334) / 5, list[0]);
+ }
+ }
+
+ [Test]
+ public void CanMinProjectionOnIdentityProjection()
+ {
+ using (ISession s = OpenSession())
+ {
+ ISQLFunction arithmaticAddition = new VarArgsSQLFunction("(", "+", ")");
+ ICriteria c =
+ s.CreateCriteria(typeof (Person)).SetProjection(
+ Projections.Min(Projections.SqlFunction(arithmaticAddition, NHibernateUtil.GuessType(typeof (double)),
+ Projections.Property("IQ"), Projections.Property("ShoeSize"))));
+ IList list = c.List();
+ Assert.AreEqual(19, list[0]);
+ }
+ }
+
+ [Test]
+ public void CanMaxProjectionOnIdentityProjection()
+ {
+ using (ISession s = OpenSession())
+ {
+ ISQLFunction arithmaticAddition = new VarArgsSQLFunction("(", "+", ")");
+ ICriteria c =
+ s.CreateCriteria(typeof (Person)).SetProjection(
+ Projections.Max(Projections.SqlFunction(arithmaticAddition, NHibernateUtil.GuessType(typeof (double)),
+ Projections.Property("IQ"), Projections.Property("ShoeSize"))));
+ IList list = c.List();
+ Assert.AreEqual(108, list[0]);
+ }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Mappings.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Mappings.hbm.xml 2008-07-25 05:09:20 UTC (rev 3662)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.NHSpecificTest.NH1393">
+
+ <class name="Person" lazy="false">
+ <id name="Id">
+ <generator class="native" />
+ </id>
+ <bag name="Pets" inverse="true" lazy="false" cascade="all-delete-orphan">
+ <key column="PersonId" />
+ <one-to-many class="Pet"/>
+ <filter name="ExampleFilter" condition=":WeightVal >= Weight" />
+ </bag>
+ <property name="Name"/>
+ <property name="IQ"/>
+ <property name="ShoeSize"/>
+ </class>
+
+ <class name="Pet" lazy="false">
+ <id name="Id">
+ <generator class="native" />
+ </id>
+ <many-to-one name="Owner" column="PersonId" not-null="true"/>
+ <property name="Name"/>
+ <property name="Species"/>
+ <property name="Weight"/>
+ </class>
+
+ <filter-def name="ExampleFilter">
+ <filter-param name="WeightVal" type="int"/>
+ </filter-def>
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Person.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Person.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1393/Person.cs 2008-07-25 05:09:20 UTC (rev 3662)
@@ -0,0 +1,105 @@
+using System.Collections;
+
+namespace NHibernate.Test.NHSpecificTest.NH1393
+{
+ public class Person
+ {
+ private int id;
+ private int iq;
+ private string name;
+ private IList pets;
+ private int shoeSize;
+
+ public Person()
+ {
+ pets = new ArrayList();
+ }
+
+ public Person(string name, int iq, int shoeSize)
+ {
+ this.name = name;
+ this.iq = iq;
+ this.shoeSize = shoeSize;
+ pets = new ArrayList();
+ }
+
+ public virtual int Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual int IQ
+ {
+ get { return iq; }
+ set { iq = value; }
+ }
+
+ public virtual int ShoeSize
+ {
+ get { return shoeSize; }
+ set { shoeSize = value; }
+ }
+
+ public virtual IList Pets
+ {
+ get { return pets; }
+ protected set { pets = value; }
+ }
+ }
+
+ public class Pet
+ {
+ private int id;
+ private string name;
+ private Person owner;
+ private string species;
+ private double weight;
+
+ public Pet() {}
+
+ public Pet(string name, string species, int weight, Person owner)
+ {
+ this.name = name;
+ this.species = species;
+ this.weight = weight;
+ this.owner = owner;
+ }
+
+ public virtual int Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual string Species
+ {
+ get { return species; }
+ set { species = value; }
+ }
+
+ public virtual double Weight
+ {
+ get { return weight; }
+ set { weight = value; }
+ }
+
+ public virtual Person Owner
+ {
+ get { return owner; }
+ set { owner = value; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Fixture.cs 2008-07-25 05:09:20 UTC (rev 3662)
@@ -0,0 +1,146 @@
+using System.Collections.Generic;
+using NHibernate.Criterion;
+using NHibernate.Dialect.Function;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH1394
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ protected override void OnTearDown()
+ {
+ base.OnTearDown();
+ using (ISession session = OpenSession())
+ {
+ using (ITransaction tx = session.BeginTransaction())
+ {
+ session.Delete("from Person");
+ tx.Commit();
+ }
+ }
+ }
+
+ protected override void OnSetUp()
+ {
+ using (ISession s = OpenSession())
+ {
+ using (ITransaction tx = s.BeginTransaction())
+ {
+ Person e1 = new Person("Joe", 10, 9);
+ Person e2 = new Person("Sally", 100, 8);
+ Person e3 = new Person("Tim", 20, 7); //20
+ Person e4 = new Person("Fred", 40, 40);
+ Person e5 = new Person("Mike", 50, 50);
+ s.Save(e1);
+ s.Save(e2);
+ s.Save(e3);
+ s.Save(e4);
+ s.Save(e5);
+ Pet p0 = new Pet("Fido", "Dog", 25, e1);
+ Pet p1 = new Pet("Biff", "Dog", 9, e1);
+ Pet p2 = new Pet("Pasha", "Dog", 25, e2);
+ Pet p3 = new Pet("Lord", "Dog", 10, e2);
+ Pet p4 = new Pet("Max", "Dog", 25, e3);
+ Pet p5 = new Pet("Min", "Dog", 8, e3);
+ s.Save(p0);
+ s.Save(p1);
+ s.Save(p2);
+ s.Save(p3);
+ s.Save(p4);
+ s.Save(p5);
+ tx.Commit();
+ }
+ }
+ }
+
+ [Test]
+ public void CanOrderByPropertyProjection()
+ {
+ using (ISession s = OpenSession())
+ {
+ ICriteria c = s.CreateCriteria(typeof (Person)).AddOrder(Order.Desc(Projections.Property("IQ")));
+ IList<Person> list = c.List<Person>();
+
+ for (int i = 0; i < list.Count - 1; i++)
+ {
+ Assert.IsTrue(list[i].IQ >= list[i + 1].IQ);
+ }
+ }
+ }
+
+ [Test]
+ public void CanOrderBySubqueryProjection()
+ {
+ using (ISession s = OpenSession())
+ {
+ DetachedCriteria dc = DetachedCriteria.For<Person>("sub");
+ dc.CreateCriteria("Pets", "pets").SetProjection(Projections.Min("pets.Weight")).Add(
+ Restrictions.EqProperty("this.Id", "sub.Id"));
+
+ ICriteria c = s.CreateCriteria(typeof (Person)).AddOrder(Order.Asc(Projections.SubQuery(dc)));
+ IList<Person> list = c.List<Person>();
+
+ Assert.AreEqual(list[2].Name, "Tim");
+ Assert.AreEqual(list[3].Name, "Joe");
+ Assert.AreEqual(list[4].Name, "Sally");
+ }
+ }
+
+ [Test]
+ public void CanOrderBySubqueryProjectionDesc()
+ {
+ using (ISession s = OpenSession())
+ {
+ DetachedCriteria dc = DetachedCriteria.For<Person>("sub");
+ dc.CreateCriteria("Pets", "pets").SetProjection(Projections.Min("pets.Weight")).Add(
+ Restrictions.EqProperty("this.Id", "sub.Id"));
+
+ ICriteria c = s.CreateCriteria(typeof (Person)).AddOrder(Order.Desc(Projections.SubQuery(dc)));
+ IList<Person> list = c.List<Person>();
+
+ Assert.AreEqual(list[2].Name, "Tim");
+ Assert.AreEqual(list[1].Name, "Joe");
+ Assert.AreEqual(list[0].Name, "Sally");
+ }
+ }
+
+ [Test]
+ public void CanOrderBySqlProjectionAsc()
+ {
+ using (ISession s = OpenSession())
+ {
+ ISQLFunction arithmaticAddition = new VarArgsSQLFunction("(", "+", ")");
+ ICriteria c =
+ s.CreateCriteria(typeof (Person)).AddOrder(
+ Order.Asc(Projections.SqlFunction(arithmaticAddition, NHibernateUtil.GuessType(typeof (double)),
+ Projections.Property("IQ"), Projections.Property("ShoeSize"))));
+ IList<Person> list = c.List<Person>();
+
+ for (int i = 0; i < list.Count - 1; i++)
+ {
+ Assert.IsTrue(list[i].IQ + list[i].ShoeSize <= list[i + 1].IQ + list[i + 1].ShoeSize);
+ }
+ }
+ }
+
+ [Test]
+ public void CanOrderBySqlProjectionDesc()
+ {
+ using (ISession s = OpenSession())
+ {
+ ISQLFunction arithmaticAddition = new VarArgsSQLFunction("(", "+", ")");
+ ICriteria c =
+ s.CreateCriteria(typeof (Person)).AddOrder(
+ Order.Desc(Projections.SqlFunction(arithmaticAddition, NHibernateUtil.GuessType(typeof (double)),
+ Projections.Property("IQ"), Projections.Property("ShoeSize"))));
+ IList<Person> list = c.List<Person>();
+
+ for (int i = 0; i < list.Count - 1; i++)
+ {
+ Assert.IsTrue(list[i].IQ + list[i].ShoeSize >= list[i + 1].IQ + list[i + 1].ShoeSize);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Mappings.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Mappings.hbm.xml 2008-07-25 05:09:20 UTC (rev 3662)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.NHSpecificTest.NH1394">
+
+ <class name="Person" lazy="false">
+ <id name="Id">
+ <generator class="native" />
+ </id>
+ <bag name="Pets" inverse="true" lazy="false" cascade="all-delete-orphan">
+ <key column="PersonId" />
+ <one-to-many class="Pet"/>
+ <filter name="ExampleFilter" condition=":WeightVal >= Weight" />
+ </bag>
+ <property name="Name"/>
+ <property name="IQ"/>
+ <property name="ShoeSize"/>
+ </class>
+
+ <class name="Pet" lazy="false">
+ <id name="Id">
+ <generator class="native" />
+ </id>
+ <many-to-one name="Owner" column="PersonId" not-null="true"/>
+ <property name="Name"/>
+ <property name="Species"/>
+ <property name="Weight"/>
+ </class>
+
+ <filter-def name="ExampleFilter">
+ <filter-param name="WeightVal" type="int"/>
+ </filter-def>
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Person.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Person.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1394/Person.cs 2008-07-25 05:09:20 UTC (rev 3662)
@@ -0,0 +1,105 @@
+using System.Collections;
+
+namespace NHibernate.Test.NHSpecificTest.NH1394
+{
+ public class Person
+ {
+ private int id;
+ private int iq;
+ private string name;
+ private IList pets;
+ private int shoeSize;
+
+ public Person()
+ {
+ pets = new ArrayList();
+ }
+
+ public Person(string name, int iq, int shoeSize)
+ {
+ this.name = name;
+ this.iq = iq;
+ this.shoeSize = shoeSize;
+ pets = new ArrayList();
+ }
+
+ public virtual int Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual int IQ
+ {
+ get { return iq; }
+ set { iq = value; }
+ }
+
+ public virtual int ShoeSize
+ {
+ get { return shoeSize; }
+ set { shoeSize = value; }
+ }
+
+ public virtual IList Pets
+ {
+ get { return pets; }
+ protected set { pets = value; }
+ }
+ }
+
+ public class Pet
+ {
+ private int id;
+ private string name;
+ private Person owner;
+ private string species;
+ private double weight;
+
+ public Pet() {}
+
+ public Pet(string name, string species, int weight, Person owner)
+ {
+ this.name = name;
+ this.species = species;
+ this.weight = weight;
+ this.owner = owner;
+ }
+
+ public virtual int Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual string Species
+ {
+ get { return species; }
+ set { species = value; }
+ }
+
+ public virtual double Weight
+ {
+ get { return weight; }
+ set { weight = value; }
+ }
+
+ public virtual Person Owner
+ {
+ get { return owner; }
+ set { owner = value; }
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate...
[truncated message content] |
|
From: <fab...@us...> - 2008-07-25 19:38:20
|
Revision: 3667
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3667&view=rev
Author: fabiomaulo
Date: 2008-07-25 19:38:27 +0000 (Fri, 25 Jul 2008)
Log Message:
-----------
Merge r3666 (fix NH-1412- Fix NH-1304)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Mapping/Property.cs
trunk/nhibernate/src/NHibernate/Properties/BackrefPropertyAccessor.cs
trunk/nhibernate/src/NHibernate/Properties/BasicPropertyAccessor.cs
trunk/nhibernate/src/NHibernate/Properties/ChainedPropertyAccessor.cs
trunk/nhibernate/src/NHibernate/Properties/EmbeddedPropertyAccessor.cs
trunk/nhibernate/src/NHibernate/Properties/FieldAccessor.cs
trunk/nhibernate/src/NHibernate/Properties/IPropertyAccessor.cs
trunk/nhibernate/src/NHibernate/Properties/IndexPropertyAccessor.cs
trunk/nhibernate/src/NHibernate/Properties/MapAccessor.cs
trunk/nhibernate/src/NHibernate/Properties/NoSetterAccessor.cs
trunk/nhibernate/src/NHibernate/Properties/NoopAccessor.cs
trunk/nhibernate/src/NHibernate/Tuple/Component/AbstractComponentTuplizer.cs
trunk/nhibernate/src/NHibernate/Tuple/Entity/AbstractEntityTuplizer.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH251/CustomAccessDO.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1304/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1304/Funny.cs
Modified: trunk/nhibernate/src/NHibernate/Mapping/Property.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/Property.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Mapping/Property.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -189,7 +189,8 @@
public virtual bool IsBasicPropertyAccessor
{
- get { return propertyAccessorName == null || propertyAccessorName.Equals("property"); }
+ // NH Different behavior : see IPropertyAccessor.CanAccessTroughReflectionOptimizer (ref. NH-1304)
+ get { return PropertyAccessor.CanAccessTroughReflectionOptimizer; }
}
public IDictionary<string, MetaAttribute> MetaAttributes
Modified: trunk/nhibernate/src/NHibernate/Properties/BackrefPropertyAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/BackrefPropertyAccessor.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Properties/BackrefPropertyAccessor.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -30,6 +30,11 @@
return new BackrefSetter();
}
+ public bool CanAccessTroughReflectionOptimizer
+ {
+ get { return false; }
+ }
+
#endregion
/// <summary> The Setter implementation for id backrefs.</summary>
Modified: trunk/nhibernate/src/NHibernate/Properties/BasicPropertyAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/BasicPropertyAccessor.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Properties/BasicPropertyAccessor.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -60,6 +60,11 @@
return result;
}
+ public bool CanAccessTroughReflectionOptimizer
+ {
+ get { return true; }
+ }
+
#endregion
/// <summary>
@@ -346,4 +351,4 @@
}
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Properties/ChainedPropertyAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/ChainedPropertyAccessor.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Properties/ChainedPropertyAccessor.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -48,6 +48,11 @@
throw new PropertyNotFoundException(theClass, propertyName, "setter");
}
+ public bool CanAccessTroughReflectionOptimizer
+ {
+ get { return false; }
+ }
+
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Properties/EmbeddedPropertyAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/EmbeddedPropertyAccessor.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Properties/EmbeddedPropertyAccessor.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -19,6 +19,11 @@
return new EmbeddedSetter(theClass);
}
+ public bool CanAccessTroughReflectionOptimizer
+ {
+ get { return false; }
+ }
+
#endregion
[Serializable]
Modified: trunk/nhibernate/src/NHibernate/Properties/FieldAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/FieldAccessor.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Properties/FieldAccessor.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -86,6 +86,11 @@
return new FieldSetter(GetField(theClass, fieldName), theClass, fieldName);
}
+ public bool CanAccessTroughReflectionOptimizer
+ {
+ get { return true; }
+ }
+
#endregion
private static FieldInfo GetField(System.Type type, string fieldName, System.Type originalType)
@@ -315,4 +320,4 @@
}
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Properties/IPropertyAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/IPropertyAccessor.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Properties/IPropertyAccessor.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -1,5 +1,3 @@
-using System;
-
namespace NHibernate.Properties
{
/// <summary>
@@ -36,5 +34,12 @@
/// be found in the <see cref="System.Type"/>.
/// </exception>
ISetter GetSetter(System.Type theClass, string propertyName);
+
+ #region NH specific
+ /// <summary>
+ /// Allow embedded and custom accessors to define if the ReflectionOptimizer can be used.
+ /// </summary>
+ bool CanAccessTroughReflectionOptimizer { get;}
+ #endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Properties/IndexPropertyAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/IndexPropertyAccessor.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Properties/IndexPropertyAccessor.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -32,6 +32,11 @@
throw new NotImplementedException();
}
+ public bool CanAccessTroughReflectionOptimizer
+ {
+ get { return false; }
+ }
+
#endregion
/// <summary> The Setter implementation for index backrefs.</summary>
Modified: trunk/nhibernate/src/NHibernate/Properties/MapAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/MapAccessor.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Properties/MapAccessor.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -18,6 +18,11 @@
return new MapSetter(propertyName);
}
+ public bool CanAccessTroughReflectionOptimizer
+ {
+ get { return false; }
+ }
+
#endregion
public sealed class MapSetter : ISetter
Modified: trunk/nhibernate/src/NHibernate/Properties/NoSetterAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/NoSetterAccessor.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Properties/NoSetterAccessor.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -66,6 +66,11 @@
return new FieldAccessor.FieldSetter(FieldAccessor.GetField(type, fieldName), type, fieldName);
}
+ public bool CanAccessTroughReflectionOptimizer
+ {
+ get { return true; }
+ }
+
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Properties/NoopAccessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Properties/NoopAccessor.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Properties/NoopAccessor.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -19,6 +19,11 @@
return new NoopSetter();
}
+ public bool CanAccessTroughReflectionOptimizer
+ {
+ get { return false; }
+ }
+
#endregion
/// <summary> A Getter which will always return null. It should not be called anyway.</summary>
Modified: trunk/nhibernate/src/NHibernate/Tuple/Component/AbstractComponentTuplizer.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Tuple/Component/AbstractComponentTuplizer.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Tuple/Component/AbstractComponentTuplizer.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -1,4 +1,5 @@
using System;
+using log4net;
using NHibernate.Engine;
using NHibernate.Properties;
@@ -8,6 +9,8 @@
[Serializable]
public abstract class AbstractComponentTuplizer : IComponentTuplizer
{
+ private static readonly ILog log = LogManager.GetLogger(typeof(AbstractComponentTuplizer));
+
protected internal int propertySpan;
protected internal IGetter[] getters;
protected internal ISetter[] setters;
@@ -32,6 +35,11 @@
}
i++;
}
+ if (log.IsDebugEnabled)
+ {
+ log.DebugFormat("{0} accessors found for component: {1}", foundCustomAccessor ? "Custom" : "No custom",
+ component.ComponentClassName);
+ }
hasCustomAccessors = foundCustomAccessor;
// Only to be secure that we can access to every things
Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/AbstractEntityTuplizer.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Tuple/Entity/AbstractEntityTuplizer.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate/Tuple/Entity/AbstractEntityTuplizer.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -1,5 +1,6 @@
using System.Collections;
using Iesi.Collections.Generic;
+using log4net;
using NHibernate.Engine;
using NHibernate.Id;
using NHibernate.Intercept;
@@ -13,6 +14,7 @@
/// <summary> Support for tuplizers relating to entities. </summary>
public abstract class AbstractEntityTuplizer : IEntityTuplizer
{
+ private static readonly ILog log = LogManager.GetLogger(typeof(AbstractEntityTuplizer));
private readonly EntityMetamodel entityMetamodel;
private readonly IGetter idGetter;
private readonly ISetter idSetter;
@@ -58,6 +60,11 @@
foundCustomAccessor = true;
i++;
}
+ if (log.IsDebugEnabled)
+ {
+ log.DebugFormat("{0} accessors found for entity: {1}", foundCustomAccessor ? "Custom" : "No custom",
+ mappingInfo.EntityName);
+ }
hasCustomAccessors = foundCustomAccessor;
instantiator = BuildInstantiator(mappingInfo);
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1304/Funny.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1304/Funny.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1304/Funny.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -0,0 +1,113 @@
+namespace NHibernate.Test.NHSpecificTest.NH1304
+{
+ public class Funny
+ {
+ private int id;
+ private string field;
+ private string fieldCamelcase;
+ private string _fieldCamelcaseUnderscore;
+ private string fieldlowercase;
+ private string _fieldlowercaseunderscore;
+ private string _FieldPascalcaseUnderscore;
+ private string m_FieldPascalcaseMUnderscore;
+ private string mFieldPascalcaseM;
+#pragma warning disable 649
+ private string nosetterCamelcase;
+ private string _nosetterCamelcaseUnderscore;
+ private string nosetterlowercase;
+ private string _nosetterlowercaseunderscore;
+ private string _NosetterPascalcaseUnderscore;
+ private string m_NosetterPascalcaseMUnderscore;
+ private string mNosetterPascalcase;
+#pragma warning restore 649
+
+ public virtual int Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual string Field
+ {
+ get { return field; }
+ set { field = value; }
+ }
+
+ public virtual string FieldCamelcase
+ {
+ get { return fieldCamelcase; }
+ set { fieldCamelcase = value; }
+ }
+
+ public virtual string FieldCamelcaseUnderscore
+ {
+ get { return _fieldCamelcaseUnderscore; }
+ set { _fieldCamelcaseUnderscore = value; }
+ }
+
+ public virtual string FieldLowercase
+ {
+ get { return fieldlowercase; }
+ set { fieldlowercase = value; }
+ }
+
+ public virtual string FieldLowercaseUnderscore
+ {
+ get { return _fieldlowercaseunderscore; }
+ set { _fieldlowercaseunderscore = value; }
+ }
+
+ public virtual string FieldPascalcaseUnderscore
+ {
+ get { return _FieldPascalcaseUnderscore; }
+ set { _FieldPascalcaseUnderscore = value; }
+ }
+
+ public virtual string FieldPascalcaseMUnderscore
+ {
+ get { return m_FieldPascalcaseMUnderscore; }
+ set { m_FieldPascalcaseMUnderscore = value; }
+ }
+
+ public virtual string FieldPascalcaseM
+ {
+ get { return mFieldPascalcaseM; }
+ set { mFieldPascalcaseM = value; }
+ }
+
+ public virtual string NosetterCamelcase
+ {
+ get { return nosetterCamelcase; }
+ }
+
+ public virtual string NosetterCamelcaseUnderscore
+ {
+ get { return _nosetterCamelcaseUnderscore; }
+ }
+
+ public virtual string NosetterLowercase
+ {
+ get { return nosetterlowercase; }
+ }
+
+ public virtual string NosetterLowercaseUnderscore
+ {
+ get { return _nosetterlowercaseunderscore; }
+ }
+
+ public virtual string NosetterPascalcaseUnderscore
+ {
+ get { return _NosetterPascalcaseUnderscore; }
+ }
+
+ public virtual string NosetterPascalcaseMUnderscore
+ {
+ get { return m_NosetterPascalcaseMUnderscore; }
+ }
+
+ public virtual string NosetterPascalcase
+ {
+ get { return mNosetterPascalcase; }
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH251/CustomAccessDO.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH251/CustomAccessDO.cs 2008-07-25 19:08:39 UTC (rev 3666)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH251/CustomAccessDO.cs 2008-07-25 19:38:27 UTC (rev 3667)
@@ -53,6 +53,11 @@
return new CustomSetter(propertyName);
}
+ public bool CanAccessTroughReflectionOptimizer
+ {
+ get { return false; }
+ }
+
public class CustomGetter : IGetter
{
private System.Type theClass;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-07-25 19:46:10
|
Revision: 3669
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3669&view=rev
Author: fabiomaulo
Date: 2008-07-25 19:46:18 +0000 (Fri, 25 Jul 2008)
Log Message:
-----------
Merge r3668 (minor)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs
trunk/nhibernate/src/NHibernate/Mapping/RootClass.cs
trunk/nhibernate/src/NHibernate/WrongClassException.cs
trunk/nhibernate/src/NHibernate.Test/JoinedSubclass/JoinedSubclassFixture.cs
trunk/nhibernate/src/NHibernate.Test/Subclass/SubclassFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2008-07-25 19:43:07 UTC (rev 3668)
+++ trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2008-07-25 19:46:18 UTC (rev 3669)
@@ -22,7 +22,7 @@
namespace NHibernate.Dialect
{
/// <summary>
- /// Represents a dialect of SQL implemented by a particular RDBMS. Sublcasses
+ /// Represents a dialect of SQL implemented by a particular RDBMS. Subclasses
/// implement NHibernate compatibility with different systems.
/// </summary>
/// <remarks>
Modified: trunk/nhibernate/src/NHibernate/Mapping/RootClass.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/RootClass.cs 2008-07-25 19:43:07 UTC (rev 3668)
+++ trunk/nhibernate/src/NHibernate/Mapping/RootClass.cs 2008-07-25 19:46:18 UTC (rev 3669)
@@ -10,7 +10,7 @@
{
/// <summary>
/// Declaration of a System.Type mapped with the <c><class></c> element that
- /// is the root class of a table-per-sublcass, or table-per-concrete-class
+ /// is the root class of a table-per-subclass, or table-per-concrete-class
/// inheritance heirarchy.
/// </summary>
[Serializable]
Modified: trunk/nhibernate/src/NHibernate/WrongClassException.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/WrongClassException.cs 2008-07-25 19:43:07 UTC (rev 3668)
+++ trunk/nhibernate/src/NHibernate/WrongClassException.cs 2008-07-25 19:46:18 UTC (rev 3669)
@@ -51,7 +51,7 @@
{
get
{
- return string.Format("Object with id: {0} was not of the specified sublcass: {1} ({2})", identifier, entityName, base.Message);
+ return string.Format("Object with id: {0} was not of the specified subclass: {1} ({2})", identifier, entityName, base.Message);
}
}
@@ -96,4 +96,4 @@
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate.Test/JoinedSubclass/JoinedSubclassFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/JoinedSubclass/JoinedSubclassFixture.cs 2008-07-25 19:43:07 UTC (rev 3668)
+++ trunk/nhibernate/src/NHibernate.Test/JoinedSubclass/JoinedSubclassFixture.cs 2008-07-25 19:46:18 UTC (rev 3669)
@@ -210,7 +210,7 @@
person = (Person) s.Load(typeof(Person), personId);
// the object with id=2 was loaded using the base class - lets make sure it actually loaded
- // the sublcass
+ // the subclass
Assert.AreEqual(typeof(Employee), empAsPerson.GetType(),
"even though person was queried, should have returned correct subclass.");
emp = (Employee) s.Load(typeof(Employee), empId);
@@ -266,4 +266,4 @@
s.Close();
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate.Test/Subclass/SubclassFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Subclass/SubclassFixture.cs 2008-07-25 19:43:07 UTC (rev 3668)
+++ trunk/nhibernate/src/NHibernate.Test/Subclass/SubclassFixture.cs 2008-07-25 19:46:18 UTC (rev 3669)
@@ -64,7 +64,7 @@
SubclassAssert.AreEqual(base1, base2);
// the object with id=2 was loaded using the base class - lets make sure it actually loaded
- // the sublcass
+ // the subclass
SubclassOne one2 = oneBase2 as SubclassOne;
Assert.IsNotNull(one2);
@@ -160,4 +160,4 @@
s.Close();
}
}
-}
\ No newline at end of file
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-07-25 23:55:37
|
Revision: 3672
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3672&view=rev
Author: fabiomaulo
Date: 2008-07-25 23:55:46 +0000 (Fri, 25 Jul 2008)
Log Message:
-----------
Fix NH-1413
Note:
Thanks to Ciprian Sabolovits for let us know that we are releasing a dialect with more bugs than trunk version, before NH2.0.0RC1; Thanks again.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Foo.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/PagingTest.cs
Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2008-07-25 23:37:55 UTC (rev 3671)
+++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2008-07-25 23:55:46 UTC (rev 3672)
@@ -1,15 +1,15 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using System.Text;
+using System.Text.RegularExpressions;
+using NHibernate.Mapping;
+using NHibernate.SqlCommand;
+using NHibernate.Util;
+
namespace NHibernate.Dialect
{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Data;
- using System.Text.RegularExpressions;
- using System.Text;
- using Mapping;
- using SqlCommand;
- using Util;
-
public class MsSql2005Dialect : MsSql2000Dialect
{
public MsSql2005Dialect()
@@ -66,14 +66,11 @@
sortExpressions = new string[] { "CURRENT_TIMESTAMP" };
}
- SqlStringBuilder result = new SqlStringBuilder()
- .Add("SELECT TOP ")
- .Add(last.ToString())
- .Add(" ")
- .Add(StringHelper.Join(", ", columnsOrAliases))
- .Add(" FROM (SELECT ROW_NUMBER() OVER(ORDER BY ");
+ SqlStringBuilder result =
+ new SqlStringBuilder().Add("SELECT TOP ").Add(last.ToString()).Add(" ").Add(StringHelper.Join(", ", columnsOrAliases))
+ .Add(" FROM (SELECT ROW_NUMBER() OVER(ORDER BY ");
- AppendSortExpressions(columnsOrAliases, sortExpressions, result);
+ AppendSortExpressions(columnsOrAliases, sortExpressions, result);
result.Add(") as row, ");
@@ -82,44 +79,39 @@
result.Add("query.").Add(columnsOrAliases[i]);
bool notLastColumn = i != columnsOrAliases.Count - 1;
if (notLastColumn)
+ {
result.Add(", ");
+ }
}
for (int i = 0; i < sortExpressions.Length; i++)
{
string sortExpression = RemoveSortOrderDirection(sortExpressions[i]);
- if(!columnsOrAliases.Contains(sortExpression))
+ if (!columnsOrAliases.Contains(sortExpression))
{
- result.Add(", query.__hibernate_sort_expr_")
- .Add(i.ToString())
- .Add("__");
+ result.Add(", query.__hibernate_sort_expr_").Add(i.ToString()).Add("__");
}
}
- result.Add(" FROM (")
- .Add(select);
+ result.Add(" FROM (").Add(select);
for (int i = 0; i < sortExpressions.Length; i++)
{
string sortExpression = RemoveSortOrderDirection(sortExpressions[i]);
- if(columnsOrAliases.Contains(sortExpression))
+ if (columnsOrAliases.Contains(sortExpression))
+ {
continue;
-
+ }
+
if (aliasToColumn.ContainsKey(sortExpression))
+ {
sortExpression = aliasToColumn[sortExpression];
+ }
- result.Add(", ")
- .Add(sortExpression)
- .Add(" as __hibernate_sort_expr_")
- .Add(i.ToString())
- .Add("__");
+ result.Add(", ").Add(sortExpression).Add(" as __hibernate_sort_expr_").Add(i.ToString()).Add("__");
}
- result.Add(" ")
- .Add(from)
- .Add(") query ) page WHERE page.row > ")
- .Add(offset.ToString())
- .Add(" ORDER BY ");
+ result.Add(" ").Add(from).Add(") query ) page WHERE page.row > ").Add(offset.ToString()).Add(" ORDER BY ");
AppendSortExpressions(columnsOrAliases, sortExpressions, result);
@@ -132,26 +124,29 @@
return Regex.Replace(sortExpression.Trim(), @"(\)|\s)(?i:asc|desc)$", "$1").Trim();
}
- private static void AppendSortExpressions(ICollection<string> columnsOrAliases, string[] sortExpressions, SqlStringBuilder result)
+ private static void AppendSortExpressions(ICollection<string> columnsOrAliases, string[] sortExpressions,
+ SqlStringBuilder result)
{
for (int i = 0; i < sortExpressions.Length; i++)
{
- if(i > 1)
+ if (i > 0)
+ {
result.Add(", ");
+ }
string sortExpression = RemoveSortOrderDirection(sortExpressions[i]);
- if(columnsOrAliases.Contains(sortExpression))
+ if (columnsOrAliases.Contains(sortExpression))
{
result.Add(sortExpression);
}
else
{
- result.Add("__hibernate_sort_expr_")
- .Add(i.ToString())
- .Add("__");
+ result.Add("__hibernate_sort_expr_").Add(i.ToString()).Add("__");
}
if (sortExpressions[i].Trim().ToLower().EndsWith("desc"))
+ {
result.Add(" DESC");
+ }
}
}
@@ -166,9 +161,8 @@
return fromIndex;
}
- private static void ExtractColumnOrAliasNames(SqlString select,
- out List<string> columnsOrAliases,
- out Dictionary<string, string> aliasToColumn)
+ private static void ExtractColumnOrAliasNames(SqlString select, out List<string> columnsOrAliases,
+ out Dictionary<string, string> aliasToColumn)
{
columnsOrAliases = new List<string>();
aliasToColumn = new Dictionary<string, string>();
@@ -181,19 +175,26 @@
index += 1;
if ("select".Equals(token, StringComparison.InvariantCultureIgnoreCase))
+ {
continue;
+ }
if ("distinct".Equals(token, StringComparison.InvariantCultureIgnoreCase))
+ {
continue;
+ }
if ("," == token)
+ {
continue;
+ }
if ("from".Equals(token, StringComparison.InvariantCultureIgnoreCase))
+ {
break;
+ }
//handle composite expressions like 2 * 4 as foo
- while (index < tokens.Count &&
- "as".Equals(tokens[index], StringComparison.InvariantCultureIgnoreCase) == false &&
- "," != tokens[index])
+ while (index < tokens.Count && "as".Equals(tokens[index], StringComparison.InvariantCultureIgnoreCase) == false
+ && "," != tokens[index])
{
token = token + " " + tokens[index];
index += 1;
@@ -208,13 +209,14 @@
{
int dot = token.IndexOf('.');
if (dot != -1)
+ {
alias = token.Substring(dot + 1);
+ }
}
// notice! we are checking here the existence of "as" "alias", two
// tokens from the current one
- if (index + 1 < tokens.Count &&
- "as".Equals(tokens[index], StringComparison.InvariantCultureIgnoreCase))
+ if (index + 1 < tokens.Count && "as".Equals(tokens[index], StringComparison.InvariantCultureIgnoreCase))
{
alias = tokens[index + 1];
index += 2; //skip the "as" and the alias \
@@ -232,10 +234,7 @@
/// <value><c>true</c></value>
public override bool SupportsLimit
{
- get
- {
- return true;
- }
+ get { return true; }
}
/// <summary>
@@ -245,23 +244,24 @@
/// <value><c>true</c></value>
public override bool SupportsLimitOffset
{
- get
- {
- return true;
- }
+ get { return true; }
}
protected override string GetSelectExistingObject(string name, Table table)
{
string schema = table.GetQuotedSchemaName(this);
- if (schema != null) schema += ".";
+ if (schema != null)
+ {
+ schema += ".";
+ }
string objName = string.Format("{0}{1}", schema, Quote(name));
string parentName = string.Format("{0}{1}", schema, table.GetQuotedName(this));
- return string.Format("select 1 from sys.objects where object_id = OBJECT_ID(N'{0}') AND parent_object_id = OBJECT_ID('{1}')",
- objName, parentName);
+ return
+ string.Format(
+ "select 1 from sys.objects where object_id = OBJECT_ID(N'{0}') AND parent_object_id = OBJECT_ID('{1}')", objName,
+ parentName);
}
-
/// <summary>
/// Sql Server 2005 supports a query statement that provides <c>LIMIT</c>
/// functionality with an offset.
@@ -269,10 +269,7 @@
/// <value><c>false</c></value>
public override bool UseMaxForLimit
{
- get
- {
- return false;
- }
+ get { return false; }
}
/// <summary>
@@ -376,7 +373,7 @@
currentToken.Length = 0;
state = TokenizerState.WhiteSpace;
}
- else if (ch == ',')// stop current token, and send the , as well
+ else if (ch == ',') // stop current token, and send the , as well
{
yield return currentToken.ToString();
currentToken.Length = 0;
@@ -404,7 +401,9 @@
}
}
if (currentToken.Length > 0)
+ {
yield return currentToken.ToString();
+ }
}
public IEnumerator GetEnumerator()
@@ -426,4 +425,4 @@
}
}
}
-}
+}
\ No newline at end of file
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Foo.cs (from rev 3671, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Foo.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Foo.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Foo.cs 2008-07-25 23:55:46 UTC (rev 3672)
@@ -0,0 +1,44 @@
+using System;
+
+namespace NHibernate.Test.NHSpecificTest.NH1413
+{
+ public class Foo
+ {
+ private DateTime birthDate;
+ private string name;
+ private long oid;
+ private int version;
+
+ public Foo() {}
+
+ public Foo(string name, DateTime birthDate)
+ {
+ this.name = name;
+ this.birthDate = birthDate;
+ }
+
+ public virtual long Oid
+ {
+ get { return oid; }
+ set { oid = value; }
+ }
+
+ public virtual int Version
+ {
+ get { return version; }
+ set { version = value; }
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual DateTime BirthDate
+ {
+ get { return birthDate; }
+ set { birthDate = value; }
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Foo.cs
___________________________________________________________________
Added: svn:mergeinfo
+
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Mappings.hbm.xml (from rev 3671, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Mappings.hbm.xml)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Mappings.hbm.xml 2008-07-25 23:55:46 UTC (rev 3672)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.NHSpecificTest.NH1413">
+
+ <class name="Foo" table="XFoos">
+ <id name="Oid" column="ID">
+ <generator class="identity"/>
+ </id>
+
+ <version name="Version" column="Version" />
+
+ <property name="Name" column="Name" type="String(25)" />
+ <property name="BirthDate" column="BirthDate" />
+
+ </class>
+
+</hibernate-mapping>
Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/Mappings.hbm.xml
___________________________________________________________________
Added: svn:mergeinfo
+
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/PagingTest.cs (from rev 3671, branches/2.0.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/PagingTest.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/PagingTest.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/PagingTest.cs 2008-07-25 23:55:46 UTC (rev 3672)
@@ -0,0 +1,43 @@
+using System;
+using NHibernate.Criterion;
+using NUnit.Framework;
+using NUnit.Framework.SyntaxHelpers;
+
+namespace NHibernate.Test.NHSpecificTest.NH1413
+{
+ [TestFixture]
+ public class PagingTest : BugTestCase
+ {
+ [Test]
+ public void Bug()
+ {
+ using(ISession session = OpenSession())
+ using(ITransaction t = session.BeginTransaction())
+ {
+ session.Persist(new Foo("Foo1", DateTime.Today.AddDays(5)));
+ session.Persist(new Foo("Foo2", DateTime.Today.AddDays(1)));
+ session.Persist(new Foo("Foo3", DateTime.Today.AddDays(3)));
+ t.Commit();
+ }
+
+ DetachedCriteria criteria = DetachedCriteria.For(typeof (Foo));
+ criteria.Add(Restrictions.Like("Name", "Foo", MatchMode.Start));
+ criteria.AddOrder(Order.Desc("Name"));
+ criteria.AddOrder(Order.Asc("BirthDate"));
+ using (ISession session = OpenSession())
+ {
+ ICriteria icriteria = criteria.GetExecutableCriteria(session);
+ icriteria.SetFirstResult(0);
+ icriteria.SetMaxResults(2);
+ Assert.That(2, Is.EqualTo(icriteria.List<Foo>().Count));
+ }
+
+ using (ISession session = OpenSession())
+ using (ITransaction t = session.BeginTransaction())
+ {
+ session.Delete("from Foo");
+ t.Commit();
+ }
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1413/PagingTest.cs
___________________________________________________________________
Added: svn:mergeinfo
+
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-25 23:37:55 UTC (rev 3671)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-25 23:55:46 UTC (rev 3672)
@@ -413,6 +413,8 @@
<Compile Include="NHSpecificTest\NH1408\DbResourceKey.cs" />
<Compile Include="NHSpecificTest\NH1408\DetachedSubCriteriaTest.cs" />
<Compile Include="NHSpecificTest\NH1408\Entity.cs" />
+ <Compile Include="NHSpecificTest\NH1413\Foo.cs" />
+ <Compile Include="NHSpecificTest\NH1413\PagingTest.cs" />
<Compile Include="NHSpecificTest\NH280\Fixture.cs" />
<Compile Include="NHSpecificTest\NH280\Foo.cs" />
<Compile Include="NHSpecificTest\NH1018\Employee.cs" />
@@ -1391,6 +1393,7 @@
<EmbeddedResource Include="Any\Person.hbm.xml" />
<EmbeddedResource Include="Any\Properties.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="NHSpecificTest\NH1413\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1304\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1408\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1393\Mappings.hbm.xml" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dar...@us...> - 2008-08-06 17:44:37
|
Revision: 3696
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3696&view=rev
Author: darioquintana
Date: 2008-08-06 17:44:45 +0000 (Wed, 06 Aug 2008)
Log Message:
-----------
-3.5 sln can build with some supress warnings (618,612) at NHibernate.Test-3.5.csproj
-missed file added.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj
Modified: trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj 2008-08-02 04:50:33 UTC (rev 3695)
+++ trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj 2008-08-06 17:44:45 UTC (rev 3696)
@@ -2,7 +2,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.21022</ProductVersion>
+ <ProductVersion>9.0.30428</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{5909BFE7-93CF-4E5F-BE22-6293368AF01D}</ProjectGuid>
<OutputType>Library</OutputType>
@@ -1033,6 +1033,7 @@
<Compile Include="Type\AnsiCharType.cs" />
<Compile Include="Type\AnyType.cs" />
<Compile Include="Type\AbstractCharType.cs" />
+ <Compile Include="Type\ClassMetaType.cs" />
<Compile Include="Type\CollectionType.cs" />
<Compile Include="Type\CustomCollectionType.cs" />
<Compile Include="Type\EmbeddedComponentType.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj 2008-08-02 04:50:33 UTC (rev 3695)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj 2008-08-06 17:44:45 UTC (rev 3696)
@@ -2,7 +2,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.21022</ProductVersion>
+ <ProductVersion>9.0.30428</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{7AEE5B37-C552-4E59-9B6F-88755BCB5070}</ProjectGuid>
<OutputType>Library</OutputType>
@@ -27,6 +27,7 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ <NoWarn>618,612</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -1345,4 +1346,4 @@
if exist "$(ProjectDir)hibernate.cfg.xml" (copy "$(ProjectDir)hibernate.cfg.xml" "hibernate.cfg.xml")
copy /y "..\..\..\NHibernate.DomainModel\ABC.hbm.xml" "ABC.hbm.xml"</PostBuildEvent>
</PropertyGroup>
-</Project>
+</Project>
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-08-13 14:59:15
|
Revision: 3701
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3701&view=rev
Author: fabiomaulo
Date: 2008-08-13 14:59:18 +0000 (Wed, 13 Aug 2008)
Log Message:
-----------
Support of parametrs in HQLFunctions (by Ricardo Stuven)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs
trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiSubstringFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiTrimEmulationFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/CharIndexFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/ClassicAggregateFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/ISQLFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/NoArgSQLFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/NvlFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/PositionSubstringFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/SQLFunctionTemplate.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSQLFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSafeSQLFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/VarArgsSQLFunction.cs
trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs
trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs
trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs
trunk/nhibernate/src/NHibernate/Hql/Classic/SelectParser.cs
trunk/nhibernate/src/NHibernate/SqlCommand/ISqlStringVisitor.cs
trunk/nhibernate/src/NHibernate/SqlCommand/QuerySelect.cs
trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs
trunk/nhibernate/src/NHibernate/SqlCommand/SqlStringBuilder.cs
trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/HQLFunctions.cs
trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/SQLFunctionTemplateTest.cs
trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/SimpleFunctionsTest.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -78,7 +78,7 @@
{
tokens.Add(replacemenToken);
}
- string functionStatement = sqlFunction.Render(tokens, criteriaQuery.Factory);
+ string functionStatement = sqlFunction.Render(tokens, criteriaQuery.Factory).ToString();
string[] splitted = functionStatement.Split(new string[] {replacemenToken}, StringSplitOptions.RemoveEmptyEntries);
SqlStringBuilder sb = new SqlStringBuilder();
@@ -138,4 +138,4 @@
return types.ToArray();
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -221,10 +221,15 @@
{
}
- public override string Render(IList args, ISessionFactoryImplementor factory)
+ public override SqlString Render(IList args, ISessionFactoryImplementor factory)
{
- base.Render(args, factory);
- return string.Format("cast('{0}' as {1})", Name, FunctionReturnType.SqlTypes(factory)[0]);
+ return new SqlStringBuilder()
+ .Add("cast('")
+ .Add(name)
+ .Add("' as ")
+ .Add(returnType.SqlTypes(factory)[0].ToString())
+ .Add(")")
+ .ToSqlString();
}
}
@@ -234,9 +239,9 @@
: base("current_timestamp", NHibernateUtil.DateTime, true)
{ }
- public override string Render(IList args, ISessionFactoryImplementor factory)
+ public override SqlString Render(IList args, ISessionFactoryImplementor factory)
{
- return Name;
+ return new SqlString(name);
}
}
@@ -245,4 +250,4 @@
return new FirebirdDataBaseSchema(connection);
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiSubstringFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiSubstringFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiSubstringFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -39,26 +40,26 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
if (args.Count < 2 || args.Count > 3)
{
throw new QueryException("substring(): Incorrect number of parameters (expected 2 or 3, got " + args.Count + ")");
}
- StringBuilder cmd = new StringBuilder();
- cmd.Append("substring(")
- .Append(args[0])
- .Append(" from ")
- .Append(args[1]);
+ SqlStringBuilder cmd = new SqlStringBuilder();
+ cmd.Add("substring(")
+ .AddObject(args[0])
+ .Add(" from ")
+ .AddObject(args[1]);
if (args.Count > 2)
{
- cmd.Append(" for ")
- .Append(args[2]);
+ cmd.Add(" for ")
+ .AddObject(args[2]);
}
- cmd.Append(')');
- return cmd.ToString();
+ cmd.Add(")");
+ return cmd.ToSqlString();
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiTrimEmulationFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiTrimEmulationFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiTrimEmulationFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
using NHibernate.Util;
using System.Text.RegularExpressions;
@@ -79,14 +80,14 @@
/// If only trim specification is omitted, BOTH is assumed;
/// if trim character is omitted, space is assumed
/// </remarks>
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
if (args.Count < 1 || args.Count > 4)
{
throw new QueryException("function takes between 1 and 4 arguments");
}
- string firstArg = (string) args[0];
+ string firstArg = args[0].ToString();
if (args.Count == 1)
{
@@ -108,7 +109,7 @@
bool leading = true; // should leading trim-characters be trimmed?
bool trailing = true; // should trailing trim-characters be trimmed?
string trimCharacter = null; // the trim-character
- string trimSource = null; // the trim-source
+ object trimSource = null; // the trim-source
// potentialTrimCharacterArgIndex = 1 assumes that a
// trim-specification has been specified. we handle the
@@ -130,11 +131,11 @@
potentialTrimCharacterArgIndex = 0;
}
- string potentialTrimCharacter = (string) args[potentialTrimCharacterArgIndex];
- if (StringHelper.EqualsCaseInsensitive("from", potentialTrimCharacter))
+ object potentialTrimCharacter = args[potentialTrimCharacterArgIndex];
+ if (StringHelper.EqualsCaseInsensitive("from", potentialTrimCharacter.ToString()))
{
trimCharacter = "' '";
- trimSource = (string) args[potentialTrimCharacterArgIndex + 1];
+ trimSource = args[potentialTrimCharacterArgIndex + 1];
}
else if (potentialTrimCharacterArgIndex + 1 >= args.Count)
{
@@ -143,14 +144,14 @@
}
else
{
- trimCharacter = potentialTrimCharacter;
- if (StringHelper.EqualsCaseInsensitive("from", (string) args[potentialTrimCharacterArgIndex + 1]))
+ trimCharacter = potentialTrimCharacter.ToString();
+ if (StringHelper.EqualsCaseInsensitive("from", args[potentialTrimCharacterArgIndex + 1].ToString()))
{
- trimSource = (string) args[potentialTrimCharacterArgIndex + 2];
+ trimSource = args[potentialTrimCharacterArgIndex + 2];
}
else
{
- trimSource = (string) args[potentialTrimCharacterArgIndex + 1];
+ trimSource = args[potentialTrimCharacterArgIndex + 1];
}
}
@@ -208,4 +209,4 @@
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.SqlTypes;
using NHibernate.Type;
@@ -34,13 +35,13 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
if (args.Count != 2)
{
throw new QueryException("cast() requires two arguments");
}
- string typeName = (string) args[1];
+ string typeName = args[1].ToString();
string sqlType = string.Empty;
IType hqlType = TypeFactory.HeuristicType(typeName);
if (hqlType != null)
@@ -70,7 +71,13 @@
{
throw new QueryException(string.Format("invalid Hibernate type for cast(): type {0} not found", typeName));
}
- return String.Format("cast({0} as {1})", args[0], sqlType);
+ return new SqlStringBuilder()
+ .Add("cast(")
+ .AddObject(args[0])
+ .Add(" as ")
+ .Add(sqlType)
+ .Add(")")
+ .ToSqlString();
}
#endregion
@@ -89,4 +96,4 @@
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/CharIndexFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/CharIndexFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/CharIndexFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -32,7 +33,7 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
// TODO: QueryException if args.Count<2 (not present in H3.2)
bool threeArgs = args.Count > 2;
@@ -40,27 +41,27 @@
object orgString = args[1];
object start = threeArgs ? args[2] : null;
- StringBuilder buf = new StringBuilder();
- buf.Append("charindex(")
- .Append(pattern)
- .Append(", ");
+ SqlStringBuilder buf = new SqlStringBuilder();
+ buf.Add("charindex(")
+ .AddObject(pattern)
+ .Add(", ");
if (threeArgs)
{
- buf.Append("right(");
+ buf.Add("right(");
}
- buf.Append(orgString);
+ buf.AddObject(orgString);
if (threeArgs)
{
- buf.Append(", char_length(")
- .Append(orgString)
- .Append(")-(")
- .Append(start)
- .Append("-1))");
+ buf.Add(", char_length(")
+ .AddObject(orgString)
+ .Add(")-(")
+ .AddObject(start)
+ .Add("-1))");
}
- buf.Append(')');
- return buf.ToString();
+ buf.Add(")");
+ return buf.ToSqlString();
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/ClassicAggregateFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/ClassicAggregateFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/ClassicAggregateFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
using NHibernate.Util;
@@ -53,7 +54,7 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
//ANSI-SQL92 definition
//<general set function> ::=
@@ -69,22 +70,22 @@
{
throw new QueryException(string.Format("Aggregate {0}(): invalid argument '*'.", name));
}
- StringBuilder cmd = new StringBuilder();
- cmd.Append(name)
- .Append("(");
+ SqlStringBuilder cmd = new SqlStringBuilder();
+ cmd.Add(name)
+ .Add("(");
if (args.Count > 1)
{
- string firstArg = args[0].ToString();
- if (!StringHelper.EqualsCaseInsensitive("distinct", firstArg) &&
- !StringHelper.EqualsCaseInsensitive("all", firstArg))
+ object firstArg = args[0];
+ if (!StringHelper.EqualsCaseInsensitive("distinct", firstArg.ToString()) &&
+ !StringHelper.EqualsCaseInsensitive("all", firstArg.ToString()))
{
throw new QueryException(string.Format("Aggregate {0}(): token unknow {1}.", name, firstArg));
}
- cmd.Append(firstArg).Append(' ');
+ cmd.AddObject(firstArg).Add(" ");
}
- cmd.Append(args[args.Count - 1])
- .Append(')');
- return cmd.ToString();
+ cmd.AddObject(args[args.Count - 1])
+ .Add(")");
+ return cmd.ToSqlString();
}
#endregion
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/ISQLFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/ISQLFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/ISQLFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,5 +1,6 @@
using System.Collections;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -38,6 +39,6 @@
/// <param name="args">List of arguments</param>
/// <param name="factory"></param>
/// <returns>SQL fragment for the fuction.</returns>
- string Render(IList args, ISessionFactoryImplementor factory);
+ SqlString Render(IList args, ISessionFactoryImplementor factory);
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/NoArgSQLFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/NoArgSQLFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/NoArgSQLFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,5 +1,6 @@
using System.Collections;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -9,8 +10,8 @@
/// </summary>
public class NoArgSQLFunction : ISQLFunction
{
- private readonly IType returnType = null;
- private readonly string name;
+ protected readonly IType returnType = null;
+ protected readonly string name;
private readonly bool hasParenthesesIfNoArguments;
public NoArgSQLFunction(string name, IType returnType) : this(name, returnType, true)
@@ -51,15 +52,21 @@
get { return hasParenthesesIfNoArguments; }
}
- public virtual string Render(IList args, ISessionFactoryImplementor factory)
+ public virtual SqlString Render(IList args, ISessionFactoryImplementor factory)
{
if (args.Count > 0)
{
throw new QueryException("function takes no arguments: " + name);
}
- return hasParenthesesIfNoArguments ? name + "()" : name;
+ SqlStringBuilder buf = new SqlStringBuilder(2);
+ buf.Add(name);
+ if (hasParenthesesIfNoArguments)
+ {
+ buf.Add("()");
+ }
+ return buf.ToSqlString();
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/NvlFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/NvlFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/NvlFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -31,7 +32,7 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
// DONE: QueryException if args.Count==0 (not present in H3.2)
if (args.Count == 0)
@@ -43,14 +44,19 @@
args.RemoveAt(lastIndex);
if (lastIndex == 0)
{
- return last.ToString();
+ return new SqlString(last);
}
object secondLast = args[lastIndex - 1];
- string nvl = "nvl(" + secondLast + ", " + last + ")";
- args[lastIndex - 1] = nvl;
+ SqlStringBuilder nvl = new SqlStringBuilder(5)
+ .Add("nvl(")
+ .AddObject(secondLast)
+ .Add(", ")
+ .AddObject(last)
+ .Add(")");
+ args[lastIndex - 1] = nvl.ToSqlString();
return Render(args, factory);
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/PositionSubstringFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/PositionSubstringFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/PositionSubstringFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -32,7 +33,7 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
// DONE: QueryException if args.Count<2 (not present in H3.2)
if (args.Count < 2)
@@ -44,35 +45,35 @@
object orgString = args[1];
object start = threeArgs ? args[2] : null;
- StringBuilder buf = new StringBuilder();
+ SqlStringBuilder buf = new SqlStringBuilder();
if (threeArgs)
{
- buf.Append('(');
+ buf.Add("(");
}
- buf.Append("position(")
- .Append(pattern)
- .Append(" in ");
+ buf.Add("position(")
+ .AddObject(pattern)
+ .Add(" in ");
if (threeArgs)
{
- buf.Append("substring(");
+ buf.Add("substring(");
}
- buf.Append(orgString);
+ buf.AddObject(orgString);
if (threeArgs)
{
- buf.Append(", ")
- .Append(start)
- .Append(')');
+ buf.Add(", ")
+ .AddObject(start)
+ .Add(")");
}
- buf.Append(')');
+ buf.Add(")");
if (threeArgs)
{
- buf.Append('+')
- .Append(start)
- .Append("-1)");
+ buf.Add("+")
+ .AddObject(start)
+ .Add("-1)");
}
- return buf.ToString();
+ return buf.ToSqlString();
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/SQLFunctionTemplate.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/SQLFunctionTemplate.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/SQLFunctionTemplate.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -3,6 +3,7 @@
using System.Text;
using System.Text.RegularExpressions;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -98,9 +99,9 @@
/// <param name="args">args function arguments</param>
/// <param name="factory">generated SQL function call</param>
/// <returns></returns>
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
- StringBuilder buf = new StringBuilder();
+ SqlStringBuilder buf = new SqlStringBuilder();
foreach (TemplateChunk tc in chunks)
{
if (tc.ArgumentIndex != InvalidArgumentIndex)
@@ -110,15 +111,22 @@
// TODO: if (arg == null) QueryException is better ?
if (arg != null)
{
- buf.Append(arg);
+ if (arg is Parameter || arg is SqlString)
+ {
+ buf.AddObject(arg);
+ }
+ else
+ {
+ buf.Add(arg.ToString());
+ }
}
}
else
{
- buf.Append(tc.Text);
+ buf.Add(tc.Text);
}
}
- return buf.ToString();
+ return buf.ToSqlString();
}
#endregion
@@ -128,4 +136,4 @@
return template;
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSQLFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSQLFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSQLFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,6 +1,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -55,17 +56,25 @@
get { return true; }
}
- public virtual string Render(IList args, ISessionFactoryImplementor factory)
+ public virtual SqlString Render(IList args, ISessionFactoryImplementor factory)
{
- StringBuilder buf = new StringBuilder();
- buf.Append(name)
- .Append('(');
+ SqlStringBuilder buf = new SqlStringBuilder();
+ buf.Add(name)
+ .Add("(");
for (int i = 0; i < args.Count; i++)
{
- buf.Append(args[i]);
- if (i < (args.Count - 1)) buf.Append(", ");
+ object arg = args[i];
+ if (arg is Parameter || arg is SqlString)
+ {
+ buf.AddObject(arg);
+ }
+ else
+ {
+ buf.Add(arg.ToString());
+ }
+ if (i < (args.Count - 1)) buf.Add(", ");
}
- return buf.Append(')').ToString();
+ return buf.Add(")").ToSqlString();
}
#endregion
@@ -75,4 +84,4 @@
return name;
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSafeSQLFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSafeSQLFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSafeSQLFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -39,7 +40,7 @@
this.allowedArgsCount = allowedArgsCount;
}
- public override string Render(System.Collections.IList args, NHibernate.Engine.ISessionFactoryImplementor factory)
+ public override SqlString Render(System.Collections.IList args, NHibernate.Engine.ISessionFactoryImplementor factory)
{
if (args.Count!= allowedArgsCount)
{
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/VarArgsSQLFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/VarArgsSQLFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/VarArgsSQLFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -47,17 +48,17 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
- StringBuilder buf = new StringBuilder().Append(begin);
+ SqlStringBuilder buf = new SqlStringBuilder().Add(begin);
for (int i = 0; i < args.Count; i++)
{
- buf.Append(args[i]);
- if (i < args.Count - 1) buf.Append(sep);
+ buf.AddObject(args[i]);
+ if (i < args.Count - 1) buf.Add(sep);
}
- return buf.Append(end).ToString();
+ return buf.Add(end).ToSqlString();
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -30,6 +30,11 @@
result.Append(text);
}
+ void ISqlStringVisitor.String(SqlString sqlString)
+ {
+ result.Append(sqlString.ToString());
+ }
+
void ISqlStringVisitor.Parameter()
{
string name = formatter.GetParameterName(parameterIndex);
@@ -37,4 +42,4 @@
result.Append(name);
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -27,6 +27,11 @@
q.AppendGroupByToken(pathExpressionParser.WhereColumn);
pathExpressionParser.AddAssociation(q);
}
+ else if (token.StartsWith(ParserHelper.HqlVariablePrefix))
+ {
+ q.AddNamedParameter(token.Substring(1));
+ q.AppendGroupByParameter();
+ }
else
{
q.AppendGroupByToken(token);
@@ -46,4 +51,4 @@
pathExpressionParser.UseThetaStyleJoin = true;
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -45,7 +45,7 @@
private readonly IDictionary<string, IAssociationType> uniqueKeyOwnerReferences = new Dictionary<string, IAssociationType>();
private readonly IDictionary<string, IPropertyMapping> decoratedPropertyMappings = new Dictionary<string, IPropertyMapping>();
- private readonly IList scalarSelectTokens = new ArrayList(); // contains a List of strings
+ private readonly IList<SqlString> scalarSelectTokens = new List<SqlString>();
private readonly IList<SqlString> whereTokens = new List<SqlString>();
private readonly IList<SqlString> havingTokens = new List<SqlString>();
private readonly IDictionary<string, JoinSequence> joins = new LinkedHashMap<string, JoinSequence>();
@@ -174,7 +174,9 @@
for (int i = 0; i < count; i++)
{
- sql.AddSelectFragmentString(((IQueryableCollection) persisters[i]).SelectFragment(names[i], suffixes[i]));
+ sql.AddSelectFragmentString(new SqlString(
+ ((IQueryableCollection) persisters[i]).SelectFragment(
+ (string) names[i], (string) suffixes[i])));
}
}
@@ -632,16 +634,26 @@
groupByTokens.Add(new SqlString(token));
}
+ internal void AppendGroupByParameter()
+ {
+ groupByTokens.Add(SqlString.Parameter);
+ }
+
internal void AppendScalarSelectToken(string token)
{
- scalarSelectTokens.Add(token);
+ scalarSelectTokens.Add(new SqlString(token));
}
internal void AppendScalarSelectTokens(string[] tokens)
{
- scalarSelectTokens.Add(tokens);
+ scalarSelectTokens.Add(new SqlString(tokens));
}
+ internal void AppendScalarSelectParameter()
+ {
+ scalarSelectTokens.Add(SqlString.Parameter);
+ }
+
internal void AddJoin(string name, JoinSequence joinSequence)
{
if (!joins.ContainsKey(name))
@@ -747,7 +759,7 @@
owners = null;
}
- string scalarSelect = RenderScalarSelect(); //Must be done here because of side-effect! yuck...
+ SqlString scalarSelect = RenderScalarSelect(); //Must be done here because of side-effect! yuck...
int scalarSize = scalarTypes.Count;
hasScalars = scalarTypes.Count != rtsize;
@@ -846,7 +858,7 @@
{
string name = returnedTypes[k];
string suffix = size == 1 ? String.Empty : k.ToString() + StringHelper.Underscore;
- sql.AddSelectFragmentString(persisters[k].IdentifierSelectFragment(name, suffix));
+ sql.AddSelectFragmentString(new SqlString(persisters[k].IdentifierSelectFragment(name, suffix)));
}
}
@@ -856,19 +868,19 @@
for (int k = 0; k < size; k++)
{
string suffix = (size == 1) ? String.Empty : k.ToString() + StringHelper.Underscore;
- string name = returnedTypes[k];
- sql.AddSelectFragmentString(persisters[k].PropertySelectFragment(name, suffix, false));
+ string name = (string) returnedTypes[k];
+ sql.AddSelectFragmentString(new SqlString(persisters[k].PropertySelectFragment(name, suffix, false)));
}
}
/// <summary>
/// WARNING: side-effecty
/// </summary>
- private string RenderScalarSelect()
+ private SqlString RenderScalarSelect()
{
bool isSubselect = superQuery != null;
- StringBuilder buf = new StringBuilder(20);
+ SqlStringBuilder buf = new SqlStringBuilder();
if (scalarTypes.Count == 0)
{
@@ -881,14 +893,14 @@
string[] _names = persisters[k].IdentifierColumnNames;
for (int i = 0; i < _names.Length; i++)
{
- buf.Append(returnedTypes[k]).Append(StringHelper.Dot).Append(_names[i]);
+ buf.Add(returnedTypes[k].ToString()).Add(StringHelper.Dot.ToString()).Add(_names[i]);
if (!isSubselect)
{
- buf.Append(" as ").Append(ScalarName(k, i)...
[truncated message content] |
|
From: <fab...@us...> - 2008-08-15 05:37:39
|
Revision: 3704
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3704&view=rev
Author: fabiomaulo
Date: 2008-08-15 05:37:47 +0000 (Fri, 15 Aug 2008)
Log Message:
-----------
- Ported test for composite-id from H3.2
- Aligned constraint for "join fetch", using <bag>, between HQL and Criteria (removed NH different behavior in BasicLoader)
- Changed NH846 according the "new" behavior (the type of the collection was not the matter of the test)
Possible Breaking change:
- The alignment of constraint should break some Criteria
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs
trunk/nhibernate/src/NHibernate/Loader/BasicLoader.cs
trunk/nhibernate/src/NHibernate.Test/MultipleCollectionFetchTest/MultipleBagFetchFixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Entities.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/CompositeId/CompositeIdFixture.cs
trunk/nhibernate/src/NHibernate.Test/CompositeId/Customer.cs
trunk/nhibernate/src/NHibernate.Test/CompositeId/Customer.hbm.xml
trunk/nhibernate/src/NHibernate.Test/CompositeId/LineItem.cs
trunk/nhibernate/src/NHibernate.Test/CompositeId/LineItem.hbm.xml
trunk/nhibernate/src/NHibernate.Test/CompositeId/Order.cs
trunk/nhibernate/src/NHibernate.Test/CompositeId/Order.hbm.xml
trunk/nhibernate/src/NHibernate.Test/CompositeId/Product.cs
trunk/nhibernate/src/NHibernate.Test/CompositeId/Product.hbm.xml
Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2008-08-14 17:33:32 UTC (rev 3703)
+++ trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2008-08-15 05:37:47 UTC (rev 3704)
@@ -117,11 +117,14 @@
hasUnsafeCollection = hasUnsafeCollection || IsUnsafe(collectionPersister);
- if (count > 1 && hasUnsafeCollection)
- {
- // The comment only mentions a bag since I don't want to confuse users.
- throw new QueryException("Cannot fetch multiple collections in a single query if one of them is a bag");
- }
+ // NH : This constraint is present in BasicLoader.PostInstantiate
+ // The constraint here break some tests ported from H3.2
+ // where is possible the use of "left join fetch"
+ //if (count > 1 && hasUnsafeCollection)
+ //{
+ // // The comment only mentions a bag since I don't want to confuse users.
+ // throw new QueryException("Cannot fetch multiple collections in a single query if one of them is a bag");
+ //}
names.Add(name);
persisters.Add(collectionPersister);
Modified: trunk/nhibernate/src/NHibernate/Loader/BasicLoader.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/BasicLoader.cs 2008-08-14 17:33:32 UTC (rev 3703)
+++ trunk/nhibernate/src/NHibernate/Loader/BasicLoader.cs 2008-08-15 05:37:47 UTC (rev 3704)
@@ -57,11 +57,13 @@
{
collectionDescriptors = null;
}
- // NH Different behavior
- //if (bagCount > 1)
- //{
- // throw new HibernateException("cannot simultaneously fetch multiple bags");
- //}
+ // H3.2 : 14.3. Associations and joins
+ // Join fetching multiple collection roles also sometimes gives unexpected results for bag mappings,
+ // so be careful about how you formulate your queries in this case
+ if (bagCount > 1)
+ {
+ throw new QueryException("Cannot simultaneously fetch multiple bags.");
+ }
}
private static bool IsBag(ICollectionPersister collectionPersister)
Added: trunk/nhibernate/src/NHibernate.Test/CompositeId/CompositeIdFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/CompositeId/CompositeIdFixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/CompositeId/CompositeIdFixture.cs 2008-08-15 05:37:47 UTC (rev 3704)
@@ -0,0 +1,283 @@
+using System;
+using System.Collections;
+using NUnit.Framework;
+
+namespace NHibernate.Test.CompositeId
+{
+ [TestFixture]
+ public class CompositeIdFixture : TestCase
+ {
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override IList Mappings
+ {
+ get
+ {
+ return new string[]
+ {
+ "CompositeId.Customer.hbm.xml", "CompositeId.Order.hbm.xml", "CompositeId.LineItem.hbm.xml",
+ "CompositeId.Product.hbm.xml"
+ };
+ }
+ }
+
+ protected override string CacheConcurrencyStrategy
+ {
+ get { return null; }
+ }
+
+ [Test]
+ public void CompositeIds()
+ {
+ ISession s;
+ ITransaction t;
+ Product p2;
+ using (s = OpenSession())
+ {
+ t = s.BeginTransaction();
+
+ Product p = new Product();
+ p.ProductId = "A123";
+ p.Description = "nipple ring";
+ p.Price = 1.0m;
+ p.NumberAvailable = 1004;
+ s.Persist(p);
+
+ p2 = new Product();
+ p2.ProductId = "X525";
+ p2.Description = "nose stud";
+ p2.Price = 3.0m;
+ p2.NumberAvailable = 105;
+ s.Persist(p2);
+
+ Customer c = new Customer();
+ c.Address = "St Kilda Rd, MEL, 3000";
+ c.Name = "Virginia";
+ c.CustomerId = "C111";
+ s.Persist(c);
+
+ Order o = new Order(c);
+ o.OrderDate = DateTime.Today;
+ LineItem li = new LineItem(o, p);
+ li.Quantity = 2;
+
+ t.Commit();
+ }
+
+ using (s = OpenSession())
+ {
+ t = s.BeginTransaction();
+ Order o = s.Get<Order>(new Order.ID("C111", 0));
+ Assert.That(o.Total == 2m);
+ t.Commit();
+ }
+
+ using(s = OpenSession())
+ {
+ t = s.BeginTransaction();
+ s.CreateQuery(
+ "from Customer c left join fetch c.Orders o left join fetch o.LineItems li left join fetch li.Product p").List();
+ t.Commit();
+ }
+
+ using(s = OpenSession())
+ {
+ t = s.BeginTransaction();
+ s.CreateQuery("from Order o left join fetch o.LineItems li left join fetch li.Product p").List();
+ t.Commit();
+ }
+
+ using(s = OpenSession())
+ {
+ t = s.BeginTransaction();
+ IEnumerable iter = s.CreateQuery("select o.id, li.id from Order o join o.LineItems li").List();
+ foreach (object[] stuff in iter)
+ {
+ Assert.AreEqual(2, stuff.Length);
+ }
+ iter = s.CreateQuery("from Order o join o.LineItems li").Enumerable();
+ foreach (object[] stuff in iter)
+ {
+ Assert.AreEqual(2, stuff.Length);
+ }
+ t.Commit();
+ }
+
+ using(s = OpenSession())
+ {
+ t = s.BeginTransaction();
+ Customer c = s.Get<Customer>("C111");
+ Order o2 = new Order(c);
+ o2.OrderDate = DateTime.Today;
+ s.Flush();
+ LineItem li2 = new LineItem(o2, p2);
+ li2.Quantity = 5;
+ IList bigOrders = s.CreateQuery("from Order o where o.Total>10.0").List();
+ Assert.AreEqual(1, bigOrders.Count);
+ t.Commit();
+ }
+
+
+ using (s = OpenSession())
+ {
+ t = s.BeginTransaction();
+ s.Delete("from LineItem");
+ s.Delete("from Order");
+ s.Delete("from Customer");
+ s.Delete("from Product");
+ t.Commit();
+ }
+ }
+
+ [Test]
+ public void MultipleCollectionFetch()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+ Product p = new Product();
+ p.ProductId = "A123";
+ p.Description = "nipple ring";
+ p.Price = 1.0m;
+ p.NumberAvailable = 1004;
+ s.Persist(p);
+
+ Product p2 = new Product();
+ p2.ProductId = "X525";
+ p2.Description = "nose stud";
+ p2.Price = 3.0m;
+ p2.NumberAvailable = 105;
+ s.Persist(p2);
+
+ Customer c = new Customer();
+ c.Address = "St Kilda Rd, MEL, 3000";
+ c.Name = "Virginia";
+ c.CustomerId = "C111";
+ s.Persist(c);
+
+ Order o = new Order(c);
+ o.OrderDate = DateTime.Today;
+ LineItem li = new LineItem(o, p);
+ li.Quantity = 2;
+ LineItem li2 = new LineItem(o, p2);
+ li2.Quantity = 3;
+
+ Order o2 = new Order(c);
+ o2.OrderDate = DateTime.Today;
+ LineItem li3 = new LineItem(o2, p);
+ li3.Quantity = 1;
+ LineItem li4 = new LineItem(o2, p2);
+ li4.Quantity = 1;
+
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ c =
+ (Customer)
+ s.CreateQuery(
+ "from Customer c left join fetch c.Orders o left join fetch o.LineItems li left join fetch li.Product p").
+ UniqueResult();
+ Assert.IsTrue(NHibernateUtil.IsInitialized(c.Orders));
+ Assert.AreEqual(2, c.Orders.Count);
+ Assert.IsTrue(NHibernateUtil.IsInitialized(((Order) c.Orders[0]).LineItems));
+ Assert.IsTrue(NHibernateUtil.IsInitialized(((Order) c.Orders[1]).LineItems));
+ Assert.AreEqual(((Order) c.Orders[0]).LineItems.Count, 2);
+ Assert.AreEqual(((Order) c.Orders[1]).LineItems.Count, 2);
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ s.Delete("from LineItem");
+ s.Delete("from Order");
+ s.Delete("from Customer");
+ s.Delete("from Product");
+ t.Commit();
+ s.Close();
+ }
+
+ [Test]
+ public void NonLazyFetch()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+ Product p = new Product();
+ p.ProductId = "A123";
+ p.Description = "nipple ring";
+ p.Price = 1.0m;
+ p.NumberAvailable = 1004;
+ s.Persist(p);
+
+ Product p2 = new Product();
+ p2.ProductId = "X525";
+ p2.Description = "nose stud";
+ p2.Price = 3.0m;
+ p2.NumberAvailable = 105;
+ s.Persist(p2);
+
+ Customer c = new Customer();
+ c.Address = "St Kilda Rd, MEL, 3000";
+ c.Name = "Virginia";
+ c.CustomerId = "C111";
+ s.Persist(c);
+
+ Order o = new Order(c);
+ o.OrderDate = DateTime.Today;
+ LineItem li = new LineItem(o, p);
+ li.Quantity = 2;
+
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ o = s.Get<Order>(new Order.ID("C111", 0));
+ Assert.AreEqual(2m, o.Total);
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ o = (Order) s.CreateQuery("from Order o left join fetch o.LineItems li left join fetch li.Product p").UniqueResult();
+ Assert.IsTrue(NHibernateUtil.IsInitialized(o.LineItems));
+ li = (LineItem) o.LineItems[0];
+ Assert.IsTrue(NHibernateUtil.IsInitialized(li));
+ Assert.IsTrue(NHibernateUtil.IsInitialized(li.Product));
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ o = (Order) s.CreateQuery("from Order o").UniqueResult();
+ Assert.IsTrue(NHibernateUtil.IsInitialized(o.LineItems));
+ li = (LineItem) o.LineItems[0];
+ Assert.IsTrue(NHibernateUtil.IsInitialized(li));
+ Assert.IsFalse(NHibernateUtil.IsInitialized(li.Product));
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ s.Delete("from LineItem");
+ s.Delete("from Order");
+ s.Delete("from Customer");
+ s.Delete("from Product");
+ t.Commit();
+ s.Close();
+ }
+
+ [Test]
+ public void Query()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+ s.CreateQuery("from LineItem ol where ol.Order.Id.CustomerId = 'C111'").List();
+ t.Commit();
+ s.Close();
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/CompositeId/Customer.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/CompositeId/Customer.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/CompositeId/Customer.cs 2008-08-15 05:37:47 UTC (rev 3704)
@@ -0,0 +1,46 @@
+using System.Collections;
+using System;
+
+namespace NHibernate.Test.CompositeId
+{
+ public class Customer
+ {
+ private string customerId;
+ private string name;
+ private string address;
+ private IList orders = new ArrayList();
+
+ public virtual string CustomerId
+ {
+ get { return customerId; }
+ set { customerId = value; }
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual string Address
+ {
+ get { return address; }
+ set { address = value; }
+ }
+
+ public virtual IList Orders
+ {
+ get { return orders; }
+ set { orders = value; }
+ }
+
+ public virtual Order GenerateNewOrder(decimal total)
+ {
+ Order order = new Order(this);
+ order.OrderDate = DateTime.Today;
+ order.Total=total;
+
+ return order;
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/CompositeId/Customer.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/CompositeId/Customer.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/CompositeId/Customer.hbm.xml 2008-08-15 05:37:47 UTC (rev 3704)
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+
+ This mapping demonstrates how to map a collection
+ <key> to one of the primary key columns of an
+ associated child class with a composite key. This
+ is very useful for legacy data!
+
+-->
+
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ namespace="NHibernate.Test.CompositeId"
+ assembly="NHibernate.Test"
+ default-access="field.camelcase">
+
+ <class name="Customer">
+
+ <id name="CustomerId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="Name" not-null="true" length="100"/>
+ <property name="Address" not-null="true" length="200"/>
+
+ <list name="Orders" inverse="true" cascade="save-update">
+ <key column="customerId"/>
+ <index column="orderNumber"/>
+ <one-to-many class="Order"/>
+ </list>
+ </class>
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/CompositeId/LineItem.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/CompositeId/LineItem.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/CompositeId/LineItem.cs 2008-08-15 05:37:47 UTC (rev 3704)
@@ -0,0 +1,92 @@
+namespace NHibernate.Test.CompositeId
+{
+ public class LineItem
+ {
+ public class ID
+ {
+ private string customerId;
+ private int orderNumber;
+ private string productId;
+ public ID() {}
+ public ID(string customerId, int orderNumber, string productId)
+ {
+ this.customerId = customerId;
+ this.orderNumber = orderNumber;
+ this.productId = productId;
+ }
+
+ public string CustomerId
+ {
+ get { return customerId; }
+ set { customerId = value; }
+ }
+
+ public int OrderNumber
+ {
+ get { return orderNumber; }
+ set { orderNumber = value; }
+ }
+
+ public string ProductId
+ {
+ get { return productId; }
+ set { productId = value; }
+ }
+
+ public override bool Equals(object obj)
+ {
+ ID that = obj as ID;
+ if (that == null)
+ return false;
+
+ return customerId == that.customerId && productId == that.productId && orderNumber == that.orderNumber;
+ }
+
+ public override int GetHashCode()
+ {
+ return (customerId != null ? customerId.GetHashCode() : 37) ^
+ (productId != null ? productId.GetHashCode() : 31) ^
+ orderNumber.GetHashCode();
+ }
+ }
+ private ID id = new ID();
+ private int quantity;
+ private Order order;
+ private Product product;
+
+ public LineItem() {}
+ public LineItem(Order order, Product product)
+ {
+ this.order = order;
+ this.product = product;
+ id.OrderNumber = order.Id.OrderNumber;
+ id.CustomerId = order.Id.CustomerId;
+ id.ProductId = product.ProductId;
+ order.LineItems.Add(this);
+ }
+
+ public virtual ID Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual int Quantity
+ {
+ get { return quantity; }
+ set { quantity = value; }
+ }
+
+ public virtual Order Order
+ {
+ get { return order; }
+ set { order = value; }
+ }
+
+ public virtual Product Product
+ {
+ get { return product; }
+ set { product = value; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/CompositeId/LineItem.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/CompositeId/LineItem.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/CompositeId/LineItem.hbm.xml 2008-08-15 05:37:47 UTC (rev 3704)
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+
+ This mapping demonstrates
+
+ (1) composite keys and many-to-one associations on
+ composite keys
+
+ (2) use of insert="false" update="false" on an
+ association mapping, when the foreign key is
+ also part of the primary key
+
+-->
+
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ namespace="NHibernate.Test.CompositeId"
+ assembly="NHibernate.Test"
+ default-access="field.camelcase">
+
+ <class name="LineItem">
+
+ <composite-id name="Id" class="LineItem+ID">
+ <key-property name="CustomerId" length="10"/>
+ <key-property name="OrderNumber"/>
+ <key-property name="ProductId" length="10"/>
+ </composite-id>
+
+ <property name="Quantity"/>
+
+ <many-to-one name="Order" insert="false" update="false" not-null="true">
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </many-to-one>
+
+ <many-to-one name="Product" insert="false" update="false" not-null="true" column="productId"/>
+ </class>
+
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/CompositeId/Order.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/CompositeId/Order.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/CompositeId/Order.cs 2008-08-15 05:37:47 UTC (rev 3704)
@@ -0,0 +1,99 @@
+using System;
+using System.Collections;
+
+namespace NHibernate.Test.CompositeId
+{
+ public class Order
+ {
+ public class ID
+ {
+ private string customerId;
+ private int orderNumber;
+ public ID() {}
+
+ public ID(string customerId, int orderNumber)
+ {
+ this.customerId = customerId;
+ this.orderNumber = orderNumber;
+ }
+
+ public string CustomerId
+ {
+ get { return customerId; }
+ set { customerId = value; }
+ }
+
+ public int OrderNumber
+ {
+ get { return orderNumber; }
+ set { orderNumber = value; }
+ }
+
+ public override bool Equals(object obj)
+ {
+ ID that = obj as ID;
+ if (that == null)
+ return false;
+ return customerId == that.customerId && orderNumber == that.orderNumber;
+ }
+
+ public override int GetHashCode()
+ {
+ return (customerId != null ? customerId.GetHashCode() : 37) ^ orderNumber.GetHashCode();
+ }
+ }
+
+ private ID id = new ID();
+ private DateTime orderDate;
+ private Customer customer;
+ private IList lineItems = new ArrayList();
+ private decimal total;
+
+ public Order() {}
+ public Order(Customer customer)
+ {
+ this.customer = customer;
+ id.CustomerId = customer.CustomerId;
+ id.OrderNumber = customer.Orders.Count;
+ customer.Orders.Add(this);
+ }
+
+ public virtual ID Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual DateTime OrderDate
+ {
+ get { return orderDate; }
+ set { orderDate = value; }
+ }
+
+ public virtual Customer Customer
+ {
+ get { return customer; }
+ set { customer = value; }
+ }
+
+ public virtual IList LineItems
+ {
+ get { return lineItems; }
+ set { lineItems = value; }
+ }
+
+ public virtual decimal Total
+ {
+ get { return total; }
+ set { total = value; }
+ }
+
+ public virtual LineItem GenerateLineItem(Product product, int quantity)
+ {
+ LineItem li = new LineItem(this, product);
+ li.Quantity= quantity;
+ lineItems.Add(li);
+ return li;
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/CompositeId/Order.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/CompositeId/Order.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/CompositeId/Order.hbm.xml 2008-08-15 05:37:47 UTC (rev 3704)
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<!--
+
+ This mapping demonstrates
+
+ (1) composite keys and one-to-many associations on
+ composite keys
+
+ (2) use of insert="false" update="false" on an
+ association mapping, when the foreign key is
+ also part of the primary key
+
+ (3) use of a derived property which performs a
+ subselect against associated tables
+
+ (4) use of <synchronize/> to ensure that auto-flush
+ works correctly for an entity with a property
+ derived from other tables
+
+
+-->
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ namespace="NHibernate.Test.CompositeId"
+ assembly="NHibernate.Test"
+ default-access="field.camelcase">
+
+ <class name="Order" table="CustomerOrder">
+ <synchronize table="LineItem"/>
+ <synchronize table="Product"/>
+
+ <composite-id name="Id" class="Order+ID">
+ <key-property name="CustomerId" length="10"/>
+ <key-property name="OrderNumber"/>
+ </composite-id>
+
+ <property name="OrderDate" not-null="true"/>
+
+ <property name="Total"
+ formula="( select sum(li.quantity*p.cost) from LineItem li, Product p where li.productId = p.productId and li.customerId = customerId and li.orderNumber = orderNumber )"/>
+
+ <many-to-one name="Customer"
+ column="customerId"
+ insert="false"
+ update="false"
+ not-null="true"/>
+
+ <bag name="LineItems"
+ fetch="join"
+ lazy="false"
+ inverse="true"
+ cascade="save-update">
+ <key>
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </key>
+ <one-to-many class="LineItem"/>
+ </bag>
+
+ </class>
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/CompositeId/Product.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/CompositeId/Product.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/CompositeId/Product.cs 2008-08-15 05:37:47 UTC (rev 3704)
@@ -0,0 +1,41 @@
+namespace NHibernate.Test.CompositeId
+{
+ public class Product
+ {
+ private string productId;
+ private string description;
+ private decimal price;
+ private int numberAvailable;
+ private int numberOrdered;
+
+ public virtual string ProductId
+ {
+ get { return productId; }
+ set { productId = value; }
+ }
+
+ public virtual string Description
+ {
+ get { return description; }
+ set { description = value; }
+ }
+
+ public virtual decimal Price
+ {
+ get { return price; }
+ set { price = value; }
+ }
+
+ public virtual int NumberAvailable
+ {
+ get { return numberAvailable; }
+ set { numberAvailable = value; }
+ }
+
+ public virtual int NumberOrdered
+ {
+ get { return numberOrdered; }
+ set { numberOrdered = value; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/CompositeId/Product.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/CompositeId/Product.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/CompositeId/Product.hbm.xml 2008-08-15 05:37:47 UTC (rev 3704)
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+
+ This mapping demonstrates
+
+ (1) use of a derived property which performs a
+ subselect against an associated table
+
+ (2) use of <synchronize/> to ensure that auto-flush
+ works correctly for an entity with a property
+ derived from another table
+
+-->
+
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ namespace="NHibernate.Test.CompositeId"
+ assembly="NHibernate.Test"
+ default-access="field.camelcase">
+
+ <class name="Product">
+ <synchronize table="LineItem"/>
+
+ <id name="ProductId" length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="Description" not-null="true" length="200"/>
+ <property name="Price" length="3" column="cost"/>
+ <property name="NumberAvailable"/>
+
+ <property name="NumberOrdered"
+ formula="( select sum(li.quantity) from LineItem li where li.productId = productId )"/>
+ </class>
+
+</hibernate-mapping>
Modified: trunk/nhibernate/src/NHibernate.Test/MultipleCollectionFetchTest/MultipleBagFetchFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/MultipleCollectionFetchTest/MultipleBagFetchFixture.cs 2008-08-14 17:33:32 UTC (rev 3703)
+++ trunk/nhibernate/src/NHibernate.Test/MultipleCollectionFetchTest/MultipleBagFetchFixture.cs 2008-08-15 05:37:47 UTC (rev 3704)
@@ -32,7 +32,7 @@
}
catch (QueryException e)
{
- Assert.IsTrue(e.Message.IndexOf("multiple collections") >= 0);
+ Assert.IsTrue(e.Message.IndexOf("Cannot simultaneously fetch multiple bags") >= 0);
}
}
@@ -45,7 +45,7 @@
}
catch (QueryException e)
{
- Assert.IsTrue(e.Message.IndexOf("multiple collections") >= 0);
+ Assert.IsTrue(e.Message.IndexOf("Cannot simultaneously fetch multiple bags") >= 0);
}
}
}
Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Entities.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Entities.cs 2008-08-14 17:33:32 UTC (rev 3703)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Entities.cs 2008-08-15 05:37:47 UTC (rev 3704)
@@ -1,5 +1,6 @@
using System;
using System.Collections;
+using Iesi.Collections;
namespace NHibernate.Test.NHSpecificTest.NH826
{
@@ -12,13 +13,26 @@
get { return _id; }
set { _id = value; }
}
+
+ public override bool Equals(object obj)
+ {
+ Entity that = obj as Entity;
+ if(that == null)
+ return false;
+ return _id == that.Id;
+ }
+
+ public override int GetHashCode()
+ {
+ return _id.GetHashCode();
+ }
}
public class ActivitySet : Entity
{
- private IList _activities = new ArrayList();
+ private ISet _activities = new HashedSet();
- public IList Activities
+ public ISet Activities
{
get { return _activities; }
set { _activities = value; }
@@ -31,9 +45,9 @@
public class EvaluationActivity : Activity
{
- private IList _questions;
+ private ISet _questions;
- public IList Questions
+ public ISet Questions
{
get { return _questions; }
set { _questions = value; }
Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Fixture.cs 2008-08-14 17:33:32 UTC (rev 3703)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Fixture.cs 2008-08-15 05:37:47 UTC (rev 3704)
@@ -38,7 +38,10 @@
session.Flush();
- session.Delete(loadedActivitySet.Activities[0]);
+ foreach (object o in loadedActivitySet.Activities)
+ {
+ session.Delete(o);
+ }
session.Delete(loadedActivitySet);
transaction.Commit();
Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Mappings.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Mappings.hbm.xml 2008-08-14 17:33:32 UTC (rev 3703)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH826/Mappings.hbm.xml 2008-08-15 05:37:47 UTC (rev 3704)
@@ -6,10 +6,10 @@
<generator class="native" />
</id>
- <bag name="Activities" lazy="true" table="co_activity_set_membership" cascade="save-update" outer-join="true" inverse="false">
+ <set name="Activities" lazy="true" table="co_activity_set_membership" cascade="save-update" outer-join="true" inverse="false">
<key column="ActivitySetId" />
<many-to-many column="ActivityId" class="Activity" />
- </bag>
+ </set>
</class>
<class name="Activity" table="co_activity" discriminator-value="0">
@@ -21,10 +21,10 @@
<discriminator column="ActivityType" type="String" />
<subclass name="EvaluationActivity" discriminator-value="3">
- <bag name="Questions" lazy="true" table="" cascade="all-delete-orphan" outer-join="true" inverse="false">
+ <set name="Questions" lazy="true" table="" cascade="all-delete-orphan" outer-join="true" inverse="false">
<key column="EvaluationActivityId" />
<one-to-many class="Question" />
- </bag>
+ </set>
</subclass>
</class>
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-08-14 17:33:32 UTC (rev 3703)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-08-15 05:37:47 UTC (rev 3704)
@@ -99,7 +99,12 @@
<Compile Include="CompositeCollection\CompositeCollection.cs" />
<Compile Include="CompositeId\ClassWithCompositeId.cs" />
<Compile Include="CompositeId\ClassWithCompositeIdFixture.cs" />
+ <Compile Include="CompositeId\CompositeIdFixture.cs" />
+ <Compile Include="CompositeId\Customer.cs" />
<Compile Include="CompositeId\Id.cs" />
+ <Compile Include="CompositeId\LineItem.cs" />
+ <Compile Include="CompositeId\Order.cs" />
+ <Compile Include="CompositeId\Product.cs" />
<Compile Include="ConnectionStringTest\NamedConnectionStringFixture.cs" />
<Compile Include="ConnectionTest\AggressiveReleaseTest.cs" />
<Compile Include="ConnectionTest\ConnectionManagementTestCase.cs" />
@@ -1395,6 +1400,10 @@
<EmbeddedResource Include="DynamicEntity\Interceptor\Customer.hbm.xml" />
<EmbeddedResource Include="Any\Person.hbm.xml" />
<EmbeddedResource Include="Any\Properties....
[truncated message content] |
|
From: <fab...@us...> - 2008-08-15 21:41:40
|
Revision: 3706
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3706&view=rev
Author: fabiomaulo
Date: 2008-08-15 21:41:48 +0000 (Fri, 15 Aug 2008)
Log Message:
-----------
Start port of enhanced Id generators.
Possible breaking change:
- IPersistentIdentifierGenerator
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs
trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs
trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs
trunk/nhibernate/src/NHibernate/Dialect/Oracle9Dialect.cs
trunk/nhibernate/src/NHibernate/Dialect/PostgreSQL82Dialect.cs
trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs
trunk/nhibernate/src/NHibernate/Dialect/SQLiteDialect.cs
trunk/nhibernate/src/NHibernate/Id/Assigned.cs
trunk/nhibernate/src/NHibernate/Id/ForeignGenerator.cs
trunk/nhibernate/src/NHibernate/Id/IConfigurable.cs
trunk/nhibernate/src/NHibernate/Id/IPersistentIdentifierGenerator.cs
trunk/nhibernate/src/NHibernate/Id/IncrementGenerator.cs
trunk/nhibernate/src/NHibernate/Id/SequenceGenerator.cs
trunk/nhibernate/src/NHibernate/Id/TableGenerator.cs
trunk/nhibernate/src/NHibernate/Mapping/Table.cs
trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Engine/Transaction/
trunk/nhibernate/src/NHibernate/Engine/Transaction/IIsolatedWork.cs
trunk/nhibernate/src/NHibernate/Engine/Transaction/Isolater.cs
trunk/nhibernate/src/NHibernate/Engine/TransactionHelper.cs
trunk/nhibernate/src/NHibernate/Id/Enhanced/
trunk/nhibernate/src/NHibernate/Id/Enhanced/IAccessCallback.cs
trunk/nhibernate/src/NHibernate/Id/Enhanced/IDatabaseStructure.cs
trunk/nhibernate/src/NHibernate/Id/Enhanced/IOptimizer.cs
trunk/nhibernate/src/NHibernate/Id/Enhanced/OptimizerFactory.cs
trunk/nhibernate/src/NHibernate/Id/Enhanced/SequenceStructure.cs
trunk/nhibernate/src/NHibernate/Id/Enhanced/SequenceStyleGenerator.cs
trunk/nhibernate/src/NHibernate/Id/Enhanced/TableStructure.cs
trunk/nhibernate/src/NHibernate.Test/IdGen/
trunk/nhibernate/src/NHibernate.Test/IdGen/Enhanced/
trunk/nhibernate/src/NHibernate.Test/IdGen/Enhanced/SequenceStyleConfigUnitFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2008-08-15 11:25:15 UTC (rev 3705)
+++ trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -701,9 +701,14 @@
IEnumerable<IPersistentIdentifierGenerator> pIDg = IterateGenerators(dialect);
foreach (IPersistentIdentifierGenerator idGen in pIDg)
{
- string dropString = idGen.SqlDropString(dialect);
- if (dropString != null)
- script.Add(dropString);
+ string[] lines = idGen.SqlDropString(dialect);
+ if (lines != null)
+ {
+ foreach (string line in lines)
+ {
+ script.Add(line);
+ }
+ }
}
return script.ToArray();
Modified: trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2008-08-15 11:25:15 UTC (rev 3705)
+++ trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -393,7 +393,7 @@
/// <summary>
/// Completely optional cascading drop clause
/// </summary>
- protected virtual string CascadeConstraintsString
+ public virtual string CascadeConstraintsString
{
get { return String.Empty; }
}
@@ -669,7 +669,7 @@
/// <summary>
/// Does the dialect support the syntax 'drop table if exists NAME'
/// </summary>
- protected virtual bool SupportsIfExistsBeforeTableName
+ public virtual bool SupportsIfExistsBeforeTableName
{
get { return false; }
}
@@ -677,7 +677,7 @@
/// <summary>
/// Does the dialect support the syntax 'drop table NAME if exists'
/// </summary>
- protected virtual bool SupportsIfExistsAfterTableName
+ public virtual bool SupportsIfExistsAfterTableName
{
get { return false; }
}
Modified: trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs 2008-08-15 11:25:15 UTC (rev 3705)
+++ trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -112,7 +112,7 @@
get { return '`'; }
}
- protected override bool SupportsIfExistsBeforeTableName
+ public override bool SupportsIfExistsBeforeTableName
{
get { return true; }
}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Oracle9Dialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Oracle9Dialect.cs 2008-08-15 11:25:15 UTC (rev 3705)
+++ trunk/nhibernate/src/NHibernate/Dialect/Oracle9Dialect.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -162,7 +162,7 @@
}
/// <summary></summary>
- protected override string CascadeConstraintsString
+ public override string CascadeConstraintsString
{
get { return " cascade constraints"; }
}
Modified: trunk/nhibernate/src/NHibernate/Dialect/PostgreSQL82Dialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/PostgreSQL82Dialect.cs 2008-08-15 11:25:15 UTC (rev 3705)
+++ trunk/nhibernate/src/NHibernate/Dialect/PostgreSQL82Dialect.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -18,7 +18,7 @@
RegisterColumnType(DbType.Guid, "uuid");
}
- protected override bool SupportsIfExistsBeforeTableName
+ public override bool SupportsIfExistsBeforeTableName
{
get { return true; }
}
Modified: trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs 2008-08-15 11:25:15 UTC (rev 3705)
+++ trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -77,7 +77,7 @@
get { return false; }
}
- protected override string CascadeConstraintsString
+ public override string CascadeConstraintsString
{
get { return " cascade"; }
}
Modified: trunk/nhibernate/src/NHibernate/Dialect/SQLiteDialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/SQLiteDialect.cs 2008-08-15 11:25:15 UTC (rev 3705)
+++ trunk/nhibernate/src/NHibernate/Dialect/SQLiteDialect.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -79,7 +79,7 @@
get { return true; }
}
- protected override bool SupportsIfExistsBeforeTableName
+ public override bool SupportsIfExistsBeforeTableName
{
get { return true; }
}
Added: trunk/nhibernate/src/NHibernate/Engine/Transaction/IIsolatedWork.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/Transaction/IIsolatedWork.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Engine/Transaction/IIsolatedWork.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -0,0 +1,18 @@
+using System.Data;
+
+namespace NHibernate.Engine.Transaction
+{
+ /// <summary>
+ /// Represents work that needs to be performed in a manner
+ /// which isolates it from any current application unit of
+ /// work transaction.
+ /// </summary>
+ public interface IIsolatedWork
+ {
+ /// <summary>
+ /// Perform the actual work to be done.
+ /// </summary>
+ /// <param name="connection">The ADP cpnnection to use.</param>
+ void DoWork(IDbConnection connection);
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Engine/Transaction/Isolater.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/Transaction/Isolater.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Engine/Transaction/Isolater.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -0,0 +1,150 @@
+using System;
+using System.Data;
+using System.Data.Common;
+using log4net;
+using NHibernate.Exceptions;
+
+namespace NHibernate.Engine.Transaction
+{
+ /// <summary>
+ /// Class which provides the isolation semantics required by
+ /// an <see cref="IIsolatedWork"/>.
+ /// </summary>
+ /// <remarks>
+ /// <list type="bullet">
+ /// <listheader>
+ /// <description>Processing comes in two flavors:</description>
+ /// </listheader>
+ /// <item>
+ /// <term><see cref="DoIsolatedWork"/> </term>
+ /// <description>makes sure the work to be done is performed in a seperate, distinct transaction</description>
+ /// </item>
+ /// <item>
+ /// <term><see cref="DoNonTransactedWork"/> </term>
+ /// <description>makes sure the work to be done is performed outside the scope of any transaction</description>
+ /// </item>
+ /// </list>
+ /// </remarks>
+ public class Isolater
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof(Isolater));
+
+ private static DoWork GetApropieateDelegate()
+ {
+ bool isAmbientTransation = System.Transactions.Transaction.Current != null;
+ if (isAmbientTransation)
+ {
+ return AmbientDelegateWork;
+ }
+ else
+ {
+ return AdoDelegateWork;
+ }
+ }
+ /// <summary>
+ /// Ensures that all processing actually performed by the given work will
+ /// occur on a seperate transaction.
+ /// </summary>
+ /// <param name="work">The work to be performed. </param>
+ /// <param name="session">The session from which this request is originating. </param>
+ public static void DoIsolatedWork(IIsolatedWork work, ISessionImplementor session)
+ {
+ DoWork worker = GetApropieateDelegate();
+ worker(session, work, true);
+ }
+
+ /// <summary>
+ /// Ensures that all processing actually performed by the given work will
+ /// occur outside of a transaction.
+ /// </summary>
+ /// <param name="work">The work to be performed. </param>
+ /// <param name="session">The session from which this request is originating. </param>
+ public static void DoNonTransactedWork(IIsolatedWork work, ISessionImplementor session)
+ {
+ DoWork worker = GetApropieateDelegate();
+ worker(session, work, false);
+ }
+
+ private delegate void DoWork(ISessionImplementor session, IIsolatedWork work, bool transacted);
+
+ private static void AdoDelegateWork(ISessionImplementor session, IIsolatedWork work, bool transacted)
+ {
+ IDbConnection connection = null;
+ IDbTransaction trans = null;
+ // bool wasAutoCommit = false;
+ try
+ {
+ connection = session.Factory.ConnectionProvider.GetConnection();
+
+ if (transacted)
+ {
+ trans = connection.BeginTransaction();
+ // TODO NH: a way to read the autocommit state is needed
+ //if (TransactionManager.GetAutoCommit(connection))
+ //{
+ // wasAutoCommit = true;
+ // TransactionManager.SetAutoCommit(connection, false);
+ //}
+ }
+
+ work.DoWork(connection);
+
+ if (transacted)
+ {
+ trans.Commit();
+ //TransactionManager.Commit(connection);
+ }
+ }
+ catch (Exception t)
+ {
+ try
+ {
+ if (transacted && connection != null && !(connection.State == ConnectionState.Closed))
+ {
+ trans.Rollback();
+ // TransactionManager.RollBack(connection);
+ }
+ }
+ catch (Exception ignore)
+ {
+ log.Debug("unable to release connection on exception [" + ignore + "]");
+ }
+
+ if (t is HibernateException)
+ {
+ throw;
+ }
+ else if (t is DbException)
+ {
+ throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, t, "error performing isolated work");
+ }
+ else
+ {
+ throw new HibernateException("error performing isolated work", t);
+ }
+ }
+ finally
+ {
+ //if (transacted && wasAutoCommit)
+ //{
+ // try
+ // {
+ // // TODO NH: reset autocommit
+ // // TransactionManager.SetAutoCommit(connection, true);
+ // }
+ // catch (Exception)
+ // {
+ // log.Debug("was unable to reset connection back to auto-commit");
+ // }
+ //}
+ session.Factory.ConnectionProvider.CloseConnection(connection);
+ }
+ }
+
+ private static void AmbientDelegateWork(ISessionImplementor session, IIsolatedWork work, bool transacted)
+ {
+ throw new NotSupportedException("Not supported yet.");
+ }
+
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Engine/TransactionHelper.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/TransactionHelper.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Engine/TransactionHelper.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -0,0 +1,53 @@
+using System.Data;
+using NHibernate.Engine.Transaction;
+using NHibernate.Exceptions;
+
+namespace NHibernate.Engine
+{
+ /// <summary>
+ /// Allows work to be done outside the current transaction, by suspending it,
+ /// and performing work in a new transaction
+ /// </summary>
+ public abstract class TransactionHelper
+ {
+ public class Work : IIsolatedWork
+ {
+ private readonly ISessionImplementor session;
+ private readonly TransactionHelper owner;
+ internal object generatedValue;
+
+ public Work(ISessionImplementor session, TransactionHelper owner)
+ {
+ this.session = session;
+ this.owner = owner;
+ }
+
+ #region Implementation of IIsolatedWork
+
+ public void DoWork(IDbConnection connection)
+ {
+ try
+ {
+ generatedValue = owner.DoWorkInCurrentTransaction(connection, null);
+ }
+ catch (System.Data.OleDb.OleDbException sqle)
+ {
+ throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle, "could not get or update next value", null);
+ }
+ }
+
+ #endregion
+ }
+
+ /// <summary> The work to be done</summary>
+ public abstract object DoWorkInCurrentTransaction(IDbConnection conn, string sql);
+
+ /// <summary> Suspend the current transaction and perform work in a new transaction</summary>
+ public virtual object DoWorkInNewTransaction(ISessionImplementor session)
+ {
+ Work work = new Work(session, this);
+ Isolater.DoIsolatedWork(work, session);
+ return work.generatedValue;
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Id/Assigned.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Id/Assigned.cs 2008-08-15 11:25:15 UTC (rev 3705)
+++ trunk/nhibernate/src/NHibernate/Id/Assigned.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -52,7 +52,7 @@
#region IConfigurable Members
- public void Configure(IType type, IDictionary<string, string> parms, Dialect.Dialect d)
+ public void Configure(IType type, IDictionary<string, string> parms, Dialect.Dialect dialect)
{
parms.TryGetValue(IdGeneratorParmsNames.EntityName, out entityName);
if (entityName == null)
Added: trunk/nhibernate/src/NHibernate/Id/Enhanced/IAccessCallback.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Id/Enhanced/IAccessCallback.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Id/Enhanced/IAccessCallback.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -0,0 +1,12 @@
+namespace NHibernate.Id.Enhanced
+{
+ /// <summary>
+ /// Contract for providing callback access to a <see cref="IDatabaseStructure"/>,
+ /// typically from the <see cref="IOptimizer"/>.
+ /// </summary>
+ public interface IAccessCallback
+ {
+ /// <summary> Retrieve the next value from the underlying source. </summary>
+ long NextValue { get;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Id/Enhanced/IDatabaseStructure.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Id/Enhanced/IDatabaseStructure.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Id/Enhanced/IDatabaseStructure.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -0,0 +1,44 @@
+using NHibernate.Engine;
+
+namespace NHibernate.Id.Enhanced
+{
+ /// <summary>
+ /// Encapsulates definition of the underlying data structure backing a sequence-style generator.
+ /// </summary>
+ public interface IDatabaseStructure
+ {
+ /// <summary> The name of the database structure (table or sequence).</summary>
+ string Name { get; }
+
+ /// <summary> How many times has this structure been accessed through this reference?</summary>
+ int TimesAccessed { get; }
+
+ /// <summary> The configured increment size</summary>
+ int IncrementSize { get; }
+
+ /// <summary>
+ /// A callback to be able to get the next value from the underlying
+ /// structure as needed.
+ /// </summary>
+ /// <param name="session">The session. </param>
+ /// <returns> The next value. </returns>
+ IAccessCallback BuildCallback(ISessionImplementor session);
+
+ /// <summary>
+ /// Prepare this structure for use. Called sometime after instantiation,
+ /// but before first use.
+ /// </summary>
+ /// <param name="optimizer">The optimizer being applied to the generator. </param>
+ void Prepare(IOptimizer optimizer);
+
+ /// <summary> Commands needed to create the underlying structures.</summary>
+ /// <param name="dialect">The database dialect being used. </param>
+ /// <returns> The creation commands. </returns>
+ string[] SqlCreateStrings(Dialect.Dialect dialect);
+
+ /// <summary> Commands needed to drop the underlying structures.</summary>
+ /// <param name="dialect">The database dialect being used. </param>
+ /// <returns> The drop commands. </returns>
+ string[] SqlDropStrings(Dialect.Dialect dialect);
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Id/Enhanced/IOptimizer.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Id/Enhanced/IOptimizer.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Id/Enhanced/IOptimizer.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -0,0 +1,54 @@
+namespace NHibernate.Id.Enhanced
+{
+ /// <summary>
+ /// Performs optimization on an optimizable identifier generator. Typically
+ /// this optimization takes the form of trying to ensure we do not have to
+ /// hit the database on each and every request to get an identifier value.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Optimizers work on constructor injection. They should provide
+ /// a constructor with the following arguments.
+ /// </para>
+ /// - <see cref="System.Type"/> The return type for the generated values.
+ /// - <langword>int</langword> The increment size.
+ /// </remarks>
+ public interface IOptimizer
+ {
+ /// <summary>
+ /// A common means to access the last value obtained from the underlying
+ /// source. This is intended for testing purposes, since accessing the
+ /// unerlying database source directly is much more difficult.
+ /// </summary>
+ /// <value>
+ /// The last value we obtained from the underlying source;
+ /// -1 indicates we have not yet consulted with the source.
+ /// </value>
+ long LastSourceValue{get;}
+ /// <summary>
+ /// Defined increment size.
+ /// </summary>
+ /// <value> The increment size.
+ /// </value>
+ int IncrementSize{get;}
+
+ /// <summary>
+ /// Generate an identifier value accounting for this specific optimization.
+ /// </summary>
+ /// <param name="callback">Callback to access the underlying value source. </param>
+ /// <returns> The generated identifier value. </returns>
+ object Generate(IAccessCallback callback);
+
+ /// <summary>
+ /// Are increments to be applied to the values stored in the underlying
+ /// value source?
+ /// </summary>
+ /// <returns>
+ /// True if the values in the source are to be incremented
+ /// according to the defined increment size; false otherwise, in which
+ /// case the increment is totally an in memory construct.
+ /// </returns>
+ bool ApplyIncrementSizeToSourceValues { get;}
+
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Id/Enhanced/OptimizerFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Id/Enhanced/OptimizerFactory.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Id/Enhanced/OptimizerFactory.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -0,0 +1,265 @@
+using System;
+using System.Reflection;
+using log4net;
+using NHibernate.Util;
+
+namespace NHibernate.Id.Enhanced
+{
+ public class OptimizerFactory
+ {
+ public const string HiLo = "hilo";
+ public const string None = "none";
+ public const string Pool = "pooled";
+ private static readonly System.Type[] CtorSignature = new System.Type[] {typeof (System.Type), typeof (int)};
+ private static readonly ILog log = LogManager.GetLogger(typeof (OptimizerFactory));
+
+ public static IOptimizer BuildOptimizer(string type, System.Type returnClass, int incrementSize)
+ {
+ if (string.IsNullOrEmpty(type))
+ {
+ throw new ArgumentNullException("type");
+ }
+ if (returnClass == null)
+ {
+ throw new ArgumentNullException("returnClass");
+ }
+ string optimizerClassName;
+ switch (type)
+ {
+ case None:
+ optimizerClassName = typeof (NoopOptimizer).FullName;
+ break;
+ case HiLo:
+ optimizerClassName = typeof (HiLoOptimizer).FullName;
+ break;
+ case Pool:
+ optimizerClassName = typeof (PooledOptimizer).FullName;
+ break;
+ default:
+ optimizerClassName = type;
+ break;
+ }
+
+ try
+ {
+ System.Type optimizerClass = ReflectHelper.ClassForName(optimizerClassName);
+ ConstructorInfo ctor = optimizerClass.GetConstructor(CtorSignature);
+ return (IOptimizer)ctor.Invoke(new object[] { returnClass, incrementSize });
+ }
+ catch (Exception)
+ {
+ // intentionally empty
+ }
+
+ // the default...
+ return new NoopOptimizer(returnClass, incrementSize);
+ }
+
+ #region Nested type: HiLoOptimizer
+
+ public class HiLoOptimizer : OptimizerSupport
+ {
+ private long hiValue;
+ private long lastSourceValue = -1;
+ private long value_Renamed;
+
+ public HiLoOptimizer(System.Type returnClass, int incrementSize) : base(returnClass, incrementSize)
+ {
+ if (incrementSize < 1)
+ {
+ throw new HibernateException("increment size cannot be less than 1");
+ }
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("creating hilo optimizer with [incrementSize=" + incrementSize + "; returnClass=" + returnClass.FullName
+ + "]");
+ }
+ }
+
+ public override long LastSourceValue
+ {
+ get { return lastSourceValue; }
+ }
+
+ public long LastValue
+ {
+ get { return value_Renamed - 1; }
+ }
+
+ public long HiValue
+ {
+ get { return hiValue; }
+ }
+
+ public override bool ApplyIncrementSizeToSourceValues
+ {
+ get { return false; }
+ }
+
+ public override object Generate(IAccessCallback callback)
+ {
+ if (lastSourceValue < 0)
+ {
+ lastSourceValue = callback.NextValue;
+ while (lastSourceValue <= 0)
+ {
+ lastSourceValue = callback.NextValue;
+ }
+ hiValue = (lastSourceValue * incrementSize) + 1;
+ value_Renamed = hiValue - incrementSize;
+ }
+ else if (value_Renamed >= hiValue)
+ {
+ lastSourceValue = callback.NextValue;
+ hiValue = (lastSourceValue * incrementSize) + 1;
+ }
+ return Make(value_Renamed++);
+ }
+ }
+
+ #endregion
+
+ #region Nested type: NoopOptimizer
+
+ public class NoopOptimizer : OptimizerSupport
+ {
+ private long lastSourceValue = -1;
+
+ public NoopOptimizer(System.Type returnClass, int incrementSize) : base(returnClass, incrementSize) {}
+
+ public override long LastSourceValue
+ {
+ get { return lastSourceValue; }
+ }
+
+ public override bool ApplyIncrementSizeToSourceValues
+ {
+ get { return false; }
+ }
+
+ public override object Generate(IAccessCallback callback)
+ {
+ if (lastSourceValue == -1)
+ {
+ while (lastSourceValue <= 0)
+ {
+ lastSourceValue = callback.NextValue;
+ }
+ }
+ else
+ {
+ lastSourceValue = callback.NextValue;
+ }
+ return Make(lastSourceValue);
+ }
+ }
+
+ #endregion
+
+ #region Nested type: OptimizerSupport
+
+ public abstract class OptimizerSupport : IOptimizer
+ {
+ protected int incrementSize;
+ protected System.Type returnClass;
+
+ protected OptimizerSupport(System.Type returnClass, int incrementSize)
+ {
+ if (returnClass == null)
+ {
+ throw new HibernateException("return class is required");
+ }
+ this.returnClass = returnClass;
+ this.incrementSize = incrementSize;
+ }
+
+ public System.Type ReturnClass
+ {
+ get { return returnClass; }
+ }
+
+ #region IOptimizer Members
+
+ public int IncrementSize
+ {
+ get { return incrementSize; }
+ }
+
+ public abstract long LastSourceValue { get; }
+
+ public abstract bool ApplyIncrementSizeToSourceValues { get; }
+ public abstract object Generate(IAccessCallback param);
+
+ #endregion
+
+ protected virtual object Make(long value)
+ {
+ return IdentifierGeneratorFactory.CreateNumber(value, returnClass);
+ }
+ }
+
+ #endregion
+
+ #region Nested type: PooledOptimizer
+
+ public class PooledOptimizer : OptimizerSupport
+ {
+ private long hiValue = -1;
+ private long value_Renamed;
+
+ public PooledOptimizer(System.Type returnClass, int incrementSize) : base(returnClass, incrementSize)
+ {
+ if (incrementSize < 1)
+ {
+ throw new HibernateException("increment size cannot be less than 1");
+ }
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("creating pooled optimizer with [incrementSize=" + incrementSize + "; returnClass="
+ + returnClass.FullName + "]");
+ }
+ }
+
+ public override long LastSourceValue
+ {
+ get { return hiValue; }
+ }
+
+ public long LastValue
+ {
+ get { return value_Renamed - 1; }
+ }
+
+ public override bool ApplyIncrementSizeToSourceValues
+ {
+ get { return true; }
+ }
+
+ public override object Generate(IAccessCallback callback)
+ {
+ if (hiValue < 0)
+ {
+ value_Renamed = callback.NextValue;
+ if (value_Renamed < 1)
+ {
+ // unfortunately not really safe to normalize this
+ // to 1 as an initial value like we do the others
+ // because we would not be able to control this if
+ // we are using a sequence...
+ log.Info("pooled optimizer source reported [" + value_Renamed
+ + "] as the initial value; use of 1 or greater highly recommended");
+ }
+ hiValue = callback.NextValue;
+ }
+ else if (value_Renamed >= hiValue)
+ {
+ hiValue = callback.NextValue;
+ value_Renamed = hiValue - incrementSize;
+ }
+ return Make(value_Renamed++);
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Id/Enhanced/SequenceStructure.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Id/Enhanced/SequenceStructure.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Id/Enhanced/SequenceStructure.cs 2008-08-15 21:41:48 UTC (rev 3706)
@@ -0,0 +1,140 @@
+using System;
+using System.Data;
+using System.Data.Common;
+using log4net;
+using NHibernate.Engine;
+using NHibernate.Exceptions;
+using NHibernate.SqlCommand;
+using NHibernate.SqlTypes;
+
+namespace NHibernate.Id.Enhanced
+{
+ /// <summary>
+ /// Describes a sequence.
+ /// </summary>
+ public class SequenceStructure : IDatabaseStructure
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof (SequenceStructure));
+ private readonly int incrementSize;
+ private readonly int initialValue;
+ private readonly string sequenceName;
+ private readonly SqlString sql;
+ private int accessCounter;
+ private bool applyIncrementSizeToSourceValues;
+
+ public SequenceStructure(Dialect.Dialect dialect, string sequenceName, int initialValue, int incrementSize)
+ {
+ this.sequenceName = sequenceName;
+ this.initialValue = initialValue;
+ this.incrementSize = incrementSize;
+ sql = new SqlString(dialect.GetSequenceNextValString(sequenceName));
+ }
+
+ #region IDatabaseStructure Members
+
+ public string Name
+ {
+ get { return sequenceName; }
+ }
+
+ public int IncrementSize
+ {
+ get { return incrementSize; }
+ }
+
+ public IAccessCallback BuildCallback(ISessionImplementor session)
+ {
+ return new SequenceAccessCallback(session, this);
+ }
+
+ public void Prepare(IOptimizer optimizer)
+ {
+ applyIncrementSizeToSourceValues = optimizer.ApplyIncrementSizeToSourceValues;
+ }
+
+ public string[] SqlCreateStrings(Dialect.Dialect dialect)
+ {
+ int sourceIncrementSize = applyIncrementSizeToSourceValues ? incrementSize : 1;
+ return dialect.GetCreateSequenceStrings(sequenceName, initialValue, sourceIncrementSize);
+ }
+
+ public string[] SqlDropStrings(Dialect.Dialect dialect)
+ {
+ return dialect.GetDropSequenceStrings(sequenceName);
+ }
+
+ public int TimesAccessed
+ {
+ get { return accessCounter; }
+ }
+
+ #endregion
+
+ #region Nested type: SequenceAccessCallback
+
+ private class SequenceAccessCallback : IAccessCallback
+ {
+ private readonly SequenceStructure owner;
+ private readonly ISessionImplementor session;
+
+ public SequenceAccessCallback(ISessionImplementor session, SequenceStructure owner)
+ {
+ this.session = session;
+ this.owner = owner;
+ }
+
+ #region IAccessCallback Members
+
+ public virtual long NextValue
+ {
+ get
+ {
+ owner.accessCounter++;
+ try
+ {
+ IDbCommand st = session.Batcher.PrepareCommand(CommandType.Text, owner.sql, new SqlType[] {SqlTypeFactory.Int64});
+ IDataReader rs = null;
+ try
+ {
+ rs = session.Batcher.ExecuteReader(st);
+ try
+ {
+ rs.Read();
+ long result = rs.GetInt64(0);
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("Sequence identifier generat...
[truncated message content] |
|
From: <fab...@us...> - 2008-08-16 04:11:10
|
Revision: 3707
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3707&view=rev
Author: fabiomaulo
Date: 2008-08-16 04:11:17 +0000 (Sat, 16 Aug 2008)
Log Message:
-----------
- Port of <natural-id> from H3.2.6
- Bug fix in statistics
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs
trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs
trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs
trunk/nhibernate/src/NHibernate/Stat/StatisticsImpl.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/Naturalid/
trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/
trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/ImmutableNaturalIdFixture.cs
trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/User.cs
trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/User.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/
trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/MutableNaturalIdFixture.cs
trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/User.cs
trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/User.hbm.xml
Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs 2008-08-15 21:41:48 UTC (rev 3706)
+++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs 2008-08-16 04:11:17 UTC (rev 3707)
@@ -32,6 +32,13 @@
protected void PropertiesFromXML(XmlNode node, PersistentClass model)
{
+ PropertiesFromXML(node, model, null, true, true, false);
+ }
+
+ protected void PropertiesFromXML(XmlNode node, PersistentClass model, UniqueKey uniqueKey, bool mutable, bool nullable, bool naturalId)
+ {
+ string entityName = model.EntityName;
+
Table table = model.Table;
foreach (XmlNode subnode in node.ChildNodes)
@@ -47,8 +54,8 @@
CollectionBinder collectionBinder = new CollectionBinder(this);
if (collectionBinder.CanCreate(name))
{
- Mapping.Collection collection = collectionBinder.Create(name, subnode, model.EntityName,
- propertyName, model, model.MappedClass);
+ Mapping.Collection collection = collectionBinder.Create(name, subnode, entityName,
+ propertyName, model, model.MappedClass);
mappings.AddCollection(collection);
value = collection;
@@ -78,7 +85,7 @@
// NH: Modified from H2.1 to allow specifying the type explicitly using class attribute
System.Type reflectedClass = GetPropertyType(subnode, model.MappedClass, propertyName);
value = new Component(model);
- BindComponent(subnode, (Component) value, reflectedClass, model.EntityName, propertyName, true);
+ BindComponent(subnode, (Component)value, reflectedClass, entityName, propertyName, true);
}
else if ("join".Equals(name))
{
@@ -98,9 +105,34 @@
else if ("filter".Equals(name))
ParseFilter(subnode, model);
+ else if ("natural-id".Equals(name))
+ {
+ UniqueKey uk = new UniqueKey();
+ uk.Name = "_UniqueKey";
+ uk.Table = table;
+ //by default, natural-ids are "immutable" (constant)
+ bool mutableId = false;
+ if (subnode.Attributes["mutable"] != null)
+ {
+ mutableId = "true".Equals(subnode.Attributes["mutable"]);
+ }
+
+ PropertiesFromXML(subnode, model, uk, mutableId, false, true);
+ table.AddUniqueKey(uk);
+ }
+
if (value != null)
- model.AddProperty(CreateProperty(value, propertyName, model.MappedClass, subnode));
+ {
+ Property property = CreateProperty(value, propertyName, model.MappedClass, subnode);
+ if (!mutable)
+ property.IsUpdateable = false;
+ if (naturalId)
+ property.IsNaturalIdentifier = true;
+ model.AddProperty(property);
+ if (uniqueKey != null)
+ uniqueKey.AddColumns(new SafetyEnumerable<Column>(property.ColumnIterator));
+ }
}
}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs 2008-08-15 21:41:48 UTC (rev 3706)
+++ trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs 2008-08-16 04:11:17 UTC (rev 3707)
@@ -727,5 +727,9 @@
return conj;
}
+ public static NaturalIdentifier NaturalId()
+ {
+ return new NaturalIdentifier();
+ }
}
}
Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs 2008-08-15 21:41:48 UTC (rev 3706)
+++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs 2008-08-16 04:11:17 UTC (rev 3707)
@@ -81,9 +81,9 @@
CheckId(entity, persister, entry.Id, entityMode);
// grab its current state
- values = persister.GetPropertyValues(entity, session.EntityMode);
+ values = persister.GetPropertyValues(entity, entityMode);
- CheckNaturalId(persister, entry.Id, values, loadedState, session);
+ CheckNaturalId(persister, entry, values, loadedState, entityMode, session);
}
return values;
}
@@ -118,30 +118,29 @@
}
}
- private void CheckNaturalId(IEntityPersister persister, object identifier, object[] current, object[] loaded, ISessionImplementor session)
+ private void CheckNaturalId(IEntityPersister persister, EntityEntry entry, object[] current, object[] loaded, EntityMode entityMode, ISessionImplementor session)
{
- // TODO NH: Natural Identifier
- //if (persister.HasNaturalIdentifier)
- //{
- // if (loaded == null)
- // {
- // loaded = session.PersistenceContext.GetNaturalIdSnapshot(identifier, persister);
- // }
- // IType[] types = persister.PropertyTypes;
- // int[] props = persister.NaturalIdentifierProperties;
- // bool[] updateable = persister.PropertyUpdateability;
- // for (int i = 0; i < props.Length; i++)
- // {
- // int prop = props[i];
- // if (!updateable[prop])
- // {
- // if (!types[prop].Equals(current[prop], loaded[prop]))
- // {
- // throw new HibernateException("immutable natural identifier of an instance of " + persister.EntityName + " was altered");
- // }
- // }
- // }
- //}
+ if (persister.HasNaturalIdentifier && entry.Status != Status.ReadOnly)
+ {
+ if (loaded == null)
+ {
+ loaded = session.PersistenceContext.GetNaturalIdSnapshot(entry.Id, persister);
+ }
+ IType[] types = persister.PropertyTypes;
+ int[] props = persister.NaturalIdentifierProperties;
+ bool[] updateable = persister.PropertyUpdateability;
+ for (int i = 0; i < props.Length; i++)
+ {
+ int prop = props[i];
+ if (!updateable[prop])
+ {
+ if (!types[prop].IsEqual(current[prop], loaded[prop], entityMode))
+ {
+ throw new HibernateException("immutable natural identifier of an instance of " + persister.EntityName + " was altered");
+ }
+ }
+ }
+ }
}
private bool WrapCollections(IEventSource session, IEntityPersister persister, IType[] types, object[] values)
Modified: trunk/nhibernate/src/NHibernate/Stat/StatisticsImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Stat/StatisticsImpl.cs 2008-08-15 21:41:48 UTC (rev 3706)
+++ trunk/nhibernate/src/NHibernate/Stat/StatisticsImpl.cs 2008-08-16 04:11:17 UTC (rev 3707)
@@ -657,7 +657,10 @@
qs.cacheHitCount++;
}
SecondLevelCacheStatistics slcs = GetSecondLevelCacheStatistics(regionName);
- slcs.hitCount++;
+ if (slcs != null)
+ {
+ slcs.hitCount++;
+ }
}
}
@@ -673,7 +676,10 @@
qs.cacheMissCount++;
}
SecondLevelCacheStatistics slcs = GetSecondLevelCacheStatistics(regionName);
- slcs.missCount++;
+ if (slcs != null)
+ {
+ slcs.missCount++;
+ }
}
}
@@ -689,7 +695,10 @@
qs.cachePutCount++;
}
SecondLevelCacheStatistics slcs = GetSecondLevelCacheStatistics(regionName);
- slcs.putCount++;
+ if (slcs != null)
+ {
+ slcs.putCount++;
+ }
}
}
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-08-15 21:41:48 UTC (rev 3706)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-08-16 04:11:17 UTC (rev 3707)
@@ -300,6 +300,10 @@
<Compile Include="MultipleCollectionFetchTest\MultipleSetFetchFixture.cs" />
<Compile Include="MultipleCollectionFetchTest\Person.cs" />
<Compile Include="MultiThreadRunner.cs" />
+ <Compile Include="Naturalid\Immutable\ImmutableNaturalIdFixture.cs" />
+ <Compile Include="Naturalid\Immutable\User.cs" />
+ <Compile Include="Naturalid\Mutable\MutableNaturalIdFixture.cs" />
+ <Compile Include="Naturalid\Mutable\User.cs" />
<Compile Include="NHAssert.cs" />
<Compile Include="NHibernateUtilTest.cs" />
<Compile Include="NHSpecificTest\AliasFixture.cs" />
@@ -1406,6 +1410,8 @@
<EmbeddedResource Include="CompositeId\Order.hbm.xml" />
<EmbeddedResource Include="CompositeId\Product.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="Naturalid\Immutable\User.hbm.xml" />
+ <EmbeddedResource Include="Naturalid\Mutable\User.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1419\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1413\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1304\Mappings.hbm.xml" />
Added: trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/ImmutableNaturalIdFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/ImmutableNaturalIdFixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/ImmutableNaturalIdFixture.cs 2008-08-16 04:11:17 UTC (rev 3707)
@@ -0,0 +1,144 @@
+using System.Collections;
+using NHibernate.Cfg;
+using NHibernate.Criterion;
+using NUnit.Framework;
+using NUnit.Framework.SyntaxHelpers;
+
+namespace NHibernate.Test.Naturalid.Immutable
+{
+ [TestFixture]
+ public class ImmutableNaturalIdFixture : TestCase
+ {
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override IList Mappings
+ {
+ get { return new string[] {"Naturalid.Immutable.User.hbm.xml"}; }
+ }
+
+ protected override void Configure(Configuration configuration)
+ {
+ cfg.SetProperty(Environment.UseSecondLevelCache, "true");
+ cfg.SetProperty(Environment.UseQueryCache, "true");
+ cfg.SetProperty(Environment.GenerateStatistics, "true");
+ }
+
+ [Test]
+ public void Update()
+ {
+ // prepare some test data...
+ User user;
+ using (ISession session = OpenSession())
+ {
+ session.BeginTransaction();
+ user = new User();
+ user.UserName = "steve";
+ user.Email = "st...@hi...";
+ user.Password = "brewhaha";
+ session.Save(user);
+ session.Transaction.Commit();
+ }
+ // 'user' is now a detached entity, so lets change a property and reattch...
+ user.Password = "homebrew";
+ using (ISession session = OpenSession())
+ {
+ session.BeginTransaction();
+ session.Update(user);
+ session.Transaction.Commit();
+ }
+
+ // clean up
+ using (ISession session = OpenSession())
+ {
+ session.BeginTransaction();
+ session.Delete(user);
+ session.Transaction.Commit();
+ }
+ }
+
+ [Test]
+ public void NaturalIdCheck()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+
+ User u = new User("steve", "superSecret");
+ s.Persist(u);
+ u.UserName = "Steve";
+ try
+ {
+ s.Flush();
+ Assert.Fail();
+ }
+ catch (HibernateException he) {}
+ u.UserName = "steve";
+ s.Delete(u);
+ t.Commit();
+ s.Close();
+ }
+
+ [Test]
+ public void NaturalIdCache()
+ {
+ ISession s = OpenSession();
+ s.BeginTransaction();
+ User u = new User("steve", "superSecret");
+ s.Persist(u);
+ s.Transaction.Commit();
+ s.Close();
+
+ sessions.Statistics.Clear();
+
+ s = OpenSession();
+ s.BeginTransaction();
+ u =
+ (User)
+ s.CreateCriteria(typeof (User)).Add(Restrictions.NaturalId().Set("UserName", "steve")).SetCacheable(true).
+ UniqueResult();
+ Assert.That(u, Is.Not.Null);
+ s.Transaction.Commit();
+ s.Close();
+
+ Assert.AreEqual(1, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(0, sessions.Statistics.QueryCacheHitCount);
+ Assert.AreEqual(1, sessions.Statistics.QueryCachePutCount);
+
+ s = OpenSession();
+ s.BeginTransaction();
+ User v = new User("gavin", "supsup");
+ s.Persist(v);
+ s.Transaction.Commit();
+ s.Close();
+
+ sessions.Statistics.Clear();
+
+ s = OpenSession();
+ s.BeginTransaction();
+ u =
+ (User)
+ s.CreateCriteria(typeof(User)).Add(Restrictions.NaturalId().Set("UserName", "steve")).SetCacheable(true).
+ UniqueResult();
+ Assert.That(u, Is.Not.Null);
+ Assert.AreEqual(0, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(1, sessions.Statistics.QueryCacheHitCount);
+ u =
+ (User)
+ s.CreateCriteria(typeof(User)).Add(Restrictions.NaturalId().Set("UserName", "steve")).SetCacheable(true).
+ UniqueResult();
+ Assert.That(u, Is.Not.Null);
+ Assert.AreEqual(0, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(2, sessions.Statistics.QueryCacheHitCount);
+ s.Transaction.Commit();
+ s.Close();
+
+ s = OpenSession();
+ s.BeginTransaction();
+ s.Delete("from User");
+ s.Transaction.Commit();
+ s.Close();
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/User.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/User.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/User.cs 2008-08-16 04:11:17 UTC (rev 3707)
@@ -0,0 +1,48 @@
+namespace NHibernate.Test.Naturalid.Immutable
+{
+ public class User
+ {
+ private int myUserId;
+ private int version;
+ private string userName;
+ private string password;
+ private string email;
+ public User() {}
+
+ public User(string userName, string password)
+ {
+ this.userName = userName;
+ this.password = password;
+ }
+
+ public virtual int MyUserId
+ {
+ get { return myUserId; }
+ set { myUserId = value; }
+ }
+
+ public virtual int Version
+ {
+ get { return version; }
+ set { version = value; }
+ }
+
+ public virtual string UserName
+ {
+ get { return userName; }
+ set { userName = value; }
+ }
+
+ public virtual string Password
+ {
+ get { return password; }
+ set { password = value; }
+ }
+
+ public virtual string Email
+ {
+ get { return email; }
+ set { email = value; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/User.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/User.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Naturalid/Immutable/User.hbm.xml 2008-08-16 04:11:17 UTC (rev 3707)
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+
+ This mapping illustrates use of <natural-id mutable="false"/>
+
+-->
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ namespace="NHibernate.Test.Naturalid.Immutable"
+ assembly="NHibernate.Test">
+
+ <class name="User" table="IMM_NAT_ID_USER" lazy="true">
+ <comment>Users may bid for or sell auction items.</comment>
+ <id name="MyUserId" type="int">
+ <generator class="increment"/>
+ </id>
+ <natural-id mutable="false">
+ <property name="UserName" length="10"/>
+ </natural-id>
+ <version name="Version"/>
+ <property name="Password" not-null="true" length="15" column="`password`"/>
+ <property name="Email"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/MutableNaturalIdFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/MutableNaturalIdFixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/MutableNaturalIdFixture.cs 2008-08-16 04:11:17 UTC (rev 3707)
@@ -0,0 +1,250 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using NHibernate.Cfg;
+using NHibernate.Criterion;
+using NUnit.Framework;
+using NUnit.Framework.SyntaxHelpers;
+using Environment=NHibernate.Cfg.Environment;
+
+namespace NHibernate.Test.Naturalid.Mutable
+{
+ [TestFixture]
+ public class MutableNaturalIdFixture : TestCase
+ {
+ // TODO : Complete the test as H3.2.6
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override IList Mappings
+ {
+ get { return new string[] {"Naturalid.Mutable.User.hbm.xml"}; }
+ }
+
+ protected override void Configure(Configuration configuration)
+ {
+ cfg.SetProperty(Environment.UseSecondLevelCache, "true");
+ cfg.SetProperty(Environment.UseQueryCache, "true");
+ cfg.SetProperty(Environment.GenerateStatistics, "true");
+ }
+
+ [Test]
+ public void ReattachmentNaturalIdCheck()
+ {
+ ISession s = OpenSession();
+ s.BeginTransaction();
+ User u = new User("gavin", "hb", "secret");
+ s.Persist(u);
+ s.Transaction.Commit();
+ s.Close();
+
+ FieldInfo name = u.GetType().GetField("name",
+ BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
+ name.SetValue(u, "Gavin");
+ s = OpenSession();
+ s.BeginTransaction();
+ try
+ {
+ s.Update(u);
+ s.Transaction.Commit();
+ }
+ catch (HibernateException)
+ {
+ s.Transaction.Rollback();
+ }
+ catch (Exception)
+ {
+ try
+ {
+ s.Transaction.Rollback();
+ }
+ catch (Exception) {}
+ throw;
+ }
+ finally
+ {
+ s.Close();
+ }
+
+ s = OpenSession();
+ s.BeginTransaction();
+ s.Delete(u);
+ s.Transaction.Commit();
+ s.Close();
+ }
+
+ [Test]
+ public void NonexistentNaturalIdCache()
+ {
+ sessions.Statistics.Clear();
+
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+
+ object nullUser =
+ s.CreateCriteria(typeof (User))
+ .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
+ .SetCacheable(true)
+ .UniqueResult();
+
+ Assert.That(nullUser, Is.Null);
+
+ t.Commit();
+ s.Close();
+
+ Assert.AreEqual(1, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(0, sessions.Statistics.QueryCacheHitCount);
+ Assert.AreEqual(0, sessions.Statistics.QueryCachePutCount);
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+
+ User u = new User("gavin", "hb", "secret");
+ s.Persist(u);
+
+ t.Commit();
+ s.Close();
+
+ sessions.Statistics.Clear();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+
+ u =(User) s.CreateCriteria(typeof (User))
+ .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
+ .SetCacheable(true).UniqueResult();
+
+ Assert.That(u, Is.Not.Null);
+
+ t.Commit();
+ s.Close();
+
+ Assert.AreEqual(1, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(0, sessions.Statistics.QueryCacheHitCount);
+ Assert.AreEqual(1, sessions.Statistics.QueryCachePutCount);
+
+ sessions.Statistics.Clear();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+
+ u =(User) s.CreateCriteria(typeof (User))
+ .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
+ .SetCacheable(true).UniqueResult();
+
+ s.Delete(u);
+
+ t.Commit();
+ s.Close();
+
+ Assert.AreEqual(0, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(1, sessions.Statistics.QueryCacheHitCount);
+
+ sessions.Statistics.Clear();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+
+ nullUser = s.CreateCriteria(typeof (User))
+ .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
+ .SetCacheable(true).UniqueResult();
+
+ Assert.That(nullUser, Is.Null);
+
+ t.Commit();
+ s.Close();
+
+ Assert.AreEqual(1, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(0, sessions.Statistics.QueryCacheHitCount);
+ Assert.AreEqual(0, sessions.Statistics.QueryCachePutCount);
+ }
+
+ [Test]
+ public void NaturalIdCache()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+
+ User u = new User("gavin", "hb", "secret");
+ s.Persist(u);
+
+ t.Commit();
+ s.Close();
+
+ sessions.Statistics.Clear();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+
+ u = (User) s.CreateCriteria(typeof (User))
+ .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
+ .SetCacheable(true).UniqueResult();
+
+ Assert.That(u, Is.Not.Null);
+
+ t.Commit();
+ s.Close();
+
+ Assert.AreEqual(1, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(0, sessions.Statistics.QueryCacheHitCount);
+ Assert.AreEqual(1, sessions.Statistics.QueryCachePutCount);
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+
+ User v = new User("xam", "hb", "foobar");
+ s.Persist(v);
+
+ t.Commit();
+ s.Close();
+
+ sessions.Statistics.Clear();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+
+ u = (User) s.CreateCriteria(typeof (User))
+ .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
+ .SetCacheable(true).UniqueResult();
+
+ Assert.That(u, Is.Not.Null);
+
+ t.Commit();
+ s.Close();
+
+ Assert.AreEqual(0, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(1, sessions.Statistics.QueryCacheHitCount);
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ s.Delete("from User");
+ t.Commit();
+ s.Close();
+ }
+
+ [Test]
+ public void Querying()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+
+ User u = new User("emmanuel", "hb", "bh");
+ s.Persist(u);
+
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+
+ u = (User) s.CreateQuery("from User u where u.name = :name").SetParameter("name", "emmanuel").UniqueResult();
+ Assert.AreEqual("emmanuel", u.Name);
+ s.Delete(u);
+
+ t.Commit();
+ s.Close();
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/User.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/User.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/User.cs 2008-08-16 04:11:17 UTC (rev 3707)
@@ -0,0 +1,34 @@
+namespace NHibernate.Test.Naturalid.Mutable
+{
+ public class User
+ {
+ private long id;
+ private readonly string name;
+ private readonly string org;
+ private string password;
+
+ public User() {}
+ public User(string name, string org, string password)
+ {
+ this.name = name;
+ this.org = org;
+ this.password = password;
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ }
+
+ public virtual string Org
+ {
+ get { return org; }
+ }
+
+ public virtual string Password
+ {
+ get { return password; }
+ set { password = value; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/User.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/User.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/User.hbm.xml 2008-08-16 04:11:17 UTC (rev 3707)
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+
+ This mapping illustrates use of <natural-id mutable="true"/>
+
+-->
+
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ namespace="NHibernate.Test.Naturalid.Mutable"
+ assembly="NHibernate.Test"
+ default-access="field">
+
+ <class name="User" table="SystemUserInfo">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <natural-id mutable="true">
+ <property name="name"/>
+ <property name="org"/>
+ </natural-id>
+ <property name="password"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-08-16 05:03:48
|
Revision: 3708
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3708&view=rev
Author: fabiomaulo
Date: 2008-08-16 05:03:56 +0000 (Sat, 16 Aug 2008)
Log Message:
-----------
Complete the port of tests for <natural-id> with bug fix and "todo" done.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs
trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs
trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/MutableNaturalIdFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs 2008-08-16 04:11:17 UTC (rev 3707)
+++ trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs 2008-08-16 05:03:56 UTC (rev 3708)
@@ -356,48 +356,46 @@
/// </summary>
public object[] GetNaturalIdSnapshot(object id, IEntityPersister persister)
{
- // todo Natural Identifier
- //if (!persister.HasNaturalIdentifier)
- //{
- // return null;
- //}
+ if (!persister.HasNaturalIdentifier)
+ {
+ return null;
+ }
- //// if the natural-id is marked as non-mutable, it is not retrieved during a
- //// normal database-snapshot operation...
- //int[] props = persister.NaturalIdentifierProperties;
- //bool[] updateable = persister.PropertyUpdateability;
- //bool allNatualIdPropsAreUpdateable = true;
- //for (int i = 0; i < props.Length; i++)
- //{
- // if (!updateable[props[i]])
- // {
- // allNatualIdPropsAreUpdateable = false;
- // break;
- // }
- //}
+ // if the natural-id is marked as non-mutable, it is not retrieved during a
+ // normal database-snapshot operation...
+ int[] props = persister.NaturalIdentifierProperties;
+ bool[] updateable = persister.PropertyUpdateability;
+ bool allNatualIdPropsAreUpdateable = true;
+ for (int i = 0; i < props.Length; i++)
+ {
+ if (!updateable[props[i]])
+ {
+ allNatualIdPropsAreUpdateable = false;
+ break;
+ }
+ }
- //if (allNatualIdPropsAreUpdateable)
- //{
- // // do this when all the properties are updateable since there is
- // // a certain likelihood that the information will already be
- // // snapshot-cached.
- // object[] entitySnapshot = GetDatabaseSnapshot(id, persister);
- // if (entitySnapshot == NoRow)
- // {
- // return null;
- // }
- // object[] naturalIdSnapshot = new object[props.Length];
- // for (int i = 0; i < props.Length; i++)
- // {
- // naturalIdSnapshot[i] = entitySnapshot[props[i]];
- // }
- // return naturalIdSnapshot;
- //}
- //else
- //{
- // return persister.GetNaturalIdentifierSnapshot(id, session);
- //}
- return null;
+ if (allNatualIdPropsAreUpdateable)
+ {
+ // do this when all the properties are updateable since there is
+ // a certain likelihood that the information will already be
+ // snapshot-cached.
+ object[] entitySnapshot = GetDatabaseSnapshot(id, persister);
+ if (entitySnapshot == NoRow)
+ {
+ return null;
+ }
+ object[] naturalIdSnapshot = new object[props.Length];
+ for (int i = 0; i < props.Length; i++)
+ {
+ naturalIdSnapshot[i] = entitySnapshot[props[i]];
+ }
+ return naturalIdSnapshot;
+ }
+ else
+ {
+ return persister.GetNaturalIdentifierSnapshot(id, session);
+ }
}
/// <summary> Add a canonical mapping from entity key to entity instance</summary>
Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs 2008-08-16 04:11:17 UTC (rev 3707)
+++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs 2008-08-16 05:03:56 UTC (rev 3708)
@@ -122,10 +122,7 @@
{
if (persister.HasNaturalIdentifier && entry.Status != Status.ReadOnly)
{
- if (loaded == null)
- {
- loaded = session.PersistenceContext.GetNaturalIdSnapshot(entry.Id, persister);
- }
+ object[] snapshot = null;
IType[] types = persister.PropertyTypes;
int[] props = persister.NaturalIdentifierProperties;
bool[] updateable = persister.PropertyUpdateability;
@@ -134,10 +131,24 @@
int prop = props[i];
if (!updateable[prop])
{
- if (!types[prop].IsEqual(current[prop], loaded[prop], entityMode))
+ object loadedVal;
+ if (loaded == null)
{
- throw new HibernateException("immutable natural identifier of an instance of " + persister.EntityName + " was altered");
+ if (snapshot == null)
+ {
+ snapshot = session.PersistenceContext.GetNaturalIdSnapshot(entry.Id, persister);
+ }
+ loadedVal = snapshot[i];
}
+ else
+ {
+ loadedVal = loaded[prop];
+ }
+ if (!types[prop].IsEqual(current[prop], loadedVal, entityMode))
+ {
+ throw new HibernateException("immutable natural identifier of an instance of " + persister.EntityName
+ + " was altered");
+ }
}
}
}
Modified: trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/MutableNaturalIdFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/MutableNaturalIdFixture.cs 2008-08-16 04:11:17 UTC (rev 3707)
+++ trunk/nhibernate/src/NHibernate.Test/Naturalid/Mutable/MutableNaturalIdFixture.cs 2008-08-16 05:03:56 UTC (rev 3708)
@@ -12,7 +12,6 @@
[TestFixture]
public class MutableNaturalIdFixture : TestCase
{
- // TODO : Complete the test as H3.2.6
protected override string MappingsAssembly
{
get { return "NHibernate.Test"; }
@@ -56,12 +55,7 @@
}
catch (Exception)
{
- try
- {
s.Transaction.Rollback();
- }
- catch (Exception) {}
- throw;
}
finally
{
@@ -84,10 +78,8 @@
ITransaction t = s.BeginTransaction();
object nullUser =
- s.CreateCriteria(typeof (User))
- .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
- .SetCacheable(true)
- .UniqueResult();
+ s.CreateCriteria(typeof (User)).Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb")).SetCacheable(
+ true).UniqueResult();
Assert.That(nullUser, Is.Null);
@@ -112,9 +104,10 @@
s = OpenSession();
t = s.BeginTransaction();
- u =(User) s.CreateCriteria(typeof (User))
- .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
- .SetCacheable(true).UniqueResult();
+ u =
+ (User)
+ s.CreateCriteria(typeof (User)).Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb")).SetCacheable(
+ true).UniqueResult();
Assert.That(u, Is.Not.Null);
@@ -130,9 +123,10 @@
s = OpenSession();
t = s.BeginTransaction();
- u =(User) s.CreateCriteria(typeof (User))
- .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
- .SetCacheable(true).UniqueResult();
+ u =
+ (User)
+ s.CreateCriteria(typeof (User)).Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb")).SetCacheable(
+ true).UniqueResult();
s.Delete(u);
@@ -147,9 +141,9 @@
s = OpenSession();
t = s.BeginTransaction();
- nullUser = s.CreateCriteria(typeof (User))
- .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
- .SetCacheable(true).UniqueResult();
+ nullUser =
+ s.CreateCriteria(typeof (User)).Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb")).SetCacheable(
+ true).UniqueResult();
Assert.That(nullUser, Is.Null);
@@ -206,16 +200,23 @@
t = s.BeginTransaction();
u = (User) s.CreateCriteria(typeof (User))
- .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
+ .Add(Restrictions.NaturalId().Set("name", "xam").Set("org", "hb"))
.SetCacheable(true).UniqueResult();
Assert.That(u, Is.Not.Null);
+ Assert.AreEqual(1, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(0, sessions.Statistics.QueryCacheHitCount);
+ u = (User)s.CreateCriteria(typeof(User))
+ .Add(Restrictions.NaturalId().Set("name", "gavin").Set("org", "hb"))
+ .SetCacheable(true).UniqueResult();
+ Assert.That(u, Is.Not.Null);
+ Assert.AreEqual(1, sessions.Statistics.QueryExecutionCount);
+ Assert.AreEqual(1, sessions.Statistics.QueryCacheHitCount);
+
t.Commit();
s.Close();
- Assert.AreEqual(0, sessions.Statistics.QueryExecutionCount);
- Assert.AreEqual(1, sessions.Statistics.QueryCacheHitCount);
s = OpenSession();
t = s.BeginTransaction();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-08-16 07:02:38
|
Revision: 3710
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3710&view=rev
Author: fabiomaulo
Date: 2008-08-16 07:02:48 +0000 (Sat, 16 Aug 2008)
Log Message:
-----------
- Fix NH-1251
- TypeFactory thread safe + refactoring NET2.0
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs
trunk/nhibernate/src/NHibernate.Test/TypesTest/TypeFactoryFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2008-08-16 06:10:38 UTC (rev 3709)
+++ trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2008-08-16 07:02:48 UTC (rev 3710)
@@ -10,6 +10,7 @@
using NHibernate.Tuple;
using NHibernate.UserTypes;
using NHibernate.Util;
+using System.Runtime.CompilerServices;
namespace NHibernate.Type
{
@@ -32,8 +33,8 @@
PrecisionScale
}
- private static char[] precisionScaleSplit = new char[] {'(', ')', ','};
- private static char[] lengthSplit = new char[] {'(', ')'};
+ private static readonly char[] precisionScaleSplit = new char[] {'(', ')', ','};
+ private static readonly char[] lengthSplit = new char[] {'(', ')'};
/*
* Maps the string representation of the type to the IType. The string
@@ -54,11 +55,16 @@
* "String(l)" -> instance of StringType with specified l
* "System.String(l)" -> instance of StringType with specified l
*/
- private static Hashtable typeByTypeOfName = Hashtable.Synchronized(new Hashtable(79));
- private static Hashtable getTypeDelegatesWithLength = Hashtable.Synchronized(new Hashtable(7));
- private static Hashtable getTypeDelegatesWithPrecision = Hashtable.Synchronized(new Hashtable(3));
+ private static readonly IDictionary<string, IType> typeByTypeOfName =
+ new ThreadSafeDictionary<string, IType>(new Dictionary<string, IType>());
+ private static readonly IDictionary<string, GetNullableTypeWithLength> getTypeDelegatesWithLength =
+ new ThreadSafeDictionary<string, GetNullableTypeWithLength>(new Dictionary<string, GetNullableTypeWithLength>());
+
+ private static readonly IDictionary<string, GetNullableTypeWithPrecision> getTypeDelegatesWithPrecision =
+ new ThreadSafeDictionary<string, GetNullableTypeWithPrecision>(new Dictionary<string, GetNullableTypeWithPrecision>());
+
private delegate NullableType GetNullableTypeWithLength(int length);
private delegate NullableType GetNullableTypeWithPrecision(byte precision, byte scale);
@@ -121,7 +127,7 @@
// add the mappings of the NHibernate specific names that are used in type=""
typeByTypeOfName[NHibernateUtil.AnsiString.Name] = NHibernateUtil.AnsiString;
- getTypeDelegatesWithLength.Add(NHibernateUtil.AnsiString.Name, new GetNullableTypeWithLength(GetAnsiStringType));
+ getTypeDelegatesWithLength.Add(NHibernateUtil.AnsiString.Name, GetAnsiStringType);
typeByTypeOfName[NHibernateUtil.AnsiChar.Name] = NHibernateUtil.AnsiChar;
typeByTypeOfName[NHibernateUtil.BinaryBlob.Name] = NHibernateUtil.BinaryBlob;
@@ -155,12 +161,12 @@
typeByTypeOfName["yes_no"] = NHibernateUtil.YesNo;
- getTypeDelegatesWithLength.Add(NHibernateUtil.Binary.Name, new GetNullableTypeWithLength(GetBinaryType));
- getTypeDelegatesWithLength.Add(NHibernateUtil.Serializable.Name, new GetNullableTypeWithLength(GetSerializableType));
- getTypeDelegatesWithLength.Add(NHibernateUtil.String.Name, new GetNullableTypeWithLength(GetStringType));
- getTypeDelegatesWithLength.Add(NHibernateUtil.Class.Name, new GetNullableTypeWithLength(GetTypeType));
+ getTypeDelegatesWithLength.Add(NHibernateUtil.Binary.Name, GetBinaryType);
+ getTypeDelegatesWithLength.Add(NHibernateUtil.Serializable.Name, GetSerializableType);
+ getTypeDelegatesWithLength.Add(NHibernateUtil.String.Name, GetStringType);
+ getTypeDelegatesWithLength.Add(NHibernateUtil.Class.Name, GetTypeType);
- getTypeDelegatesWithPrecision.Add(NHibernateUtil.Decimal.Name, new GetNullableTypeWithPrecision(GetDecimalType));
+ getTypeDelegatesWithPrecision.Add(NHibernateUtil.Decimal.Name, GetDecimalType);
}
@@ -230,13 +236,12 @@
/// </remarks>
public static IType Basic(string name)
{
- string typeName = String.Empty;
+ string typeName;
// Use the basic name (such as String or String(255)) to get the
// instance of the IType object.
IType returnType;
- returnType = (IType) typeByTypeOfName[name];
- if (returnType != null)
+ if (typeByTypeOfName.TryGetValue(name,out returnType))
{
return returnType;
}
@@ -249,9 +254,6 @@
if (typeClassification == TypeClassification.PrecisionScale)
{
//precision/scale based
- GetNullableTypeWithPrecision precisionDelegate;
- byte precision;
- byte scale;
string[] parsedName = name.Split(precisionScaleSplit);
if (parsedName.Length < 4)
@@ -261,22 +263,20 @@
}
typeName = parsedName[0].Trim();
- precision = Byte.Parse(parsedName[1].Trim());
- scale = Byte.Parse(parsedName[2].Trim());
+ byte precision = Byte.Parse(parsedName[1].Trim());
+ byte scale = Byte.Parse(parsedName[2].Trim());
- if (getTypeDelegatesWithPrecision.ContainsKey(typeName) == false)
+ GetNullableTypeWithPrecision precisionDelegate;
+ if (!getTypeDelegatesWithPrecision.TryGetValue(typeName, out precisionDelegate))
{
return null;
}
- precisionDelegate = (GetNullableTypeWithPrecision) getTypeDelegatesWithPrecision[typeName];
return precisionDelegate(precision, scale);
}
else if (typeClassification == TypeClassification.Length)
{
//length based
- GetNullableTypeWithLength lengthDelegate;
- int length;
string[] parsedName = name.Split(lengthSplit);
if (parsedName.Length < 3)
@@ -285,15 +285,15 @@
}
typeName = parsedName[0].Trim();
- length = Int32.Parse(parsedName[1].Trim());
+ int length = Int32.Parse(parsedName[1].Trim());
- if (getTypeDelegatesWithLength.ContainsKey(typeName) == false)
- // we were not able to find a delegate to get the Type
+ GetNullableTypeWithLength lengthDelegate;
+
+ if (!getTypeDelegatesWithLength.TryGetValue(typeName, out lengthDelegate))
{
+ // we were not able to find a delegate to get the Type
return null;
}
-
- lengthDelegate = (GetNullableTypeWithLength) getTypeDelegatesWithLength[typeName];
return lengthDelegate(length);
}
@@ -307,23 +307,20 @@
}
}
- private static IType AddToTypeOfName(string key, IType type)
+ private static void AddToTypeOfName(string key, IType type)
{
typeByTypeOfName.Add(key, type);
typeByTypeOfName.Add(type.Name, type);
- return type;
}
- private static IType AddToTypeOfNameWithLength(string key, IType type)
+ private static void AddToTypeOfNameWithLength(string key, IType type)
{
typeByTypeOfName.Add(key, type);
- return type;
}
- private static IType AddToTypeOfNameWithPrecision(string key, IType type)
+ private static void AddToTypeOfNameWithPrecision(string key, IType type)
{
typeByTypeOfName.Add(key, type);
- return type;
}
private static string GetKeyForLengthBased(string name, int length)
@@ -375,14 +372,8 @@
{
parsedTypeName = typeName.Split(lengthSplit);
}
- else if (typeClassification == TypeClassification.PrecisionScale)
- {
- parsedTypeName = typeName.Split(precisionScaleSplit);
- }
- else
- {
- parsedTypeName = new string[] {typeName};
- }
+ else
+ parsedTypeName = typeClassification == TypeClassification.PrecisionScale ? typeName.Split(precisionScaleSplit) : new string[] {typeName};
System.Type typeClass;
@@ -455,22 +446,19 @@
return genericClass.IsSubclassOf(typeof (Enum));
}
- /// <summary>
- ///
- /// </summary>
- /// <param name="length"></param>
- /// <returns></returns>
+
+ [MethodImpl(MethodImplOptions.Synchronized)]
public static NullableType GetAnsiStringType(int length)
{
string key = GetKeyForLengthBased(NHibernateUtil.AnsiString.Name, length);
- NullableType returnType = (NullableType) typeByTypeOfName[key];
- if (returnType == null)
+ IType returnType;
+ if (!typeByTypeOfName.TryGetValue(key, out returnType))
{
returnType = new AnsiStringType(SqlTypeFactory.GetAnsiString(length));
AddToTypeOfNameWithLength(key, returnType);
}
- return returnType;
+ return (NullableType)returnType;
}
/// <summary>
@@ -483,6 +471,7 @@
/// been added to the basicNameMap with the keys <c>Byte[](length)</c> and
/// <c>NHibernate.Type.BinaryType(length)</c>.
/// </remarks>
+ [MethodImpl(MethodImplOptions.Synchronized)]
public static NullableType GetBinaryType(int length)
{
//HACK: don't understand why SerializableType calls this with length=0
@@ -492,27 +481,28 @@
}
string key = GetKeyForLengthBased(NHibernateUtil.Binary.Name, length);
- NullableType returnType = (NullableType) typeByTypeOfName[key];
- if (returnType == null)
+ IType returnType;
+ if (!typeByTypeOfName.TryGetValue(key, out returnType))
{
returnType = new BinaryType(SqlTypeFactory.GetBinary(length));
AddToTypeOfNameWithLength(key, returnType);
}
- return returnType;
+ return (NullableType)returnType;
}
+ [MethodImpl(MethodImplOptions.Synchronized)]
public static NullableType GetDecimalType(byte precision, byte scale)
{
string key = GetKeyForPrecisionScaleBased(NHibernateUtil.Decimal.Name, precision, scale);
- NullableType returnType = (NullableType) typeByTypeOfName[key];
- if (returnType == null)
+ IType returnType;
+ if (!typeByTypeOfName.TryGetValue(key, out returnType))
{
returnType = new DecimalType(SqlTypeFactory.GetDecimal(precision, scale));
AddToTypeOfNameWithPrecision(key, returnType);
}
- return returnType;
+ return (NullableType)returnType;
}
/// <summary>
@@ -534,95 +524,79 @@
/// with the default length, those keys will also be added.
/// </para>
/// </remarks>
+ [MethodImpl(MethodImplOptions.Synchronized)]
public static NullableType GetSerializableType(System.Type serializableType)
{
string key = serializableType.AssemblyQualifiedName;
- NullableType returnType = (NullableType) typeByTypeOfName[key];
- if (returnType == null)
+ IType returnType;
+ if (!typeByTypeOfName.TryGetValue(key, out returnType))
{
returnType = new SerializableType(serializableType);
AddToTypeOfName(key, returnType);
}
- return returnType;
+ return (NullableType)returnType;
}
- /// <summary>
- ///
- /// </summary>
- /// <param name="serializableType"></param>
- /// <param name="length"></param>
- /// <returns></returns>
+ [MethodImpl(MethodImplOptions.Synchronized)]
public static NullableType GetSerializableType(System.Type serializableType, int length)
{
string key = GetKeyForLengthBased(serializableType.AssemblyQualifiedName, length);
- NullableType returnType = (NullableType) typeByTypeOfName[key];
- if (returnType == null)
+ IType returnType;
+ if (!typeByTypeOfName.TryGetValue(key, out returnType))
{
returnType = new SerializableType(serializableType, SqlTypeFactory.GetBinary(length));
AddToTypeOfNameWithLength(key, returnType);
}
- return returnType;
+ return (NullableType)returnType;
}
- /// <summary>
- ///
- /// </summary>
- /// <param name="length"></param>
- /// <returns></returns>
+ [MethodImpl(MethodImplOptions.Synchronized)]
public static NullableType GetSerializableType(int length)
{
string key = GetKeyForLengthBased(NHibernateUtil.Serializable.Name, length);
- NullableType returnType = (NullableType) typeByTypeOfName[key];
- if (returnType == null)
+ IType returnType;
+ if (!typeByTypeOfName.TryGetValue(key, out returnType))
{
returnType = new SerializableType(typeof(object), SqlTypeFactory.GetBinary(length));
AddToTypeOfNameWithLength(key, returnType);
}
- return returnType;
+ return (NullableType)returnType;
}
- /// <summary>
- ///
- /// </summary>
- /// <param name="length"></param>
- /// <returns></returns>
+ [MethodImpl(MethodImplOptions.Synchronized)]
public static NullableType GetStringType(int length)
{
string key = GetKeyForLengthBased(NHibernateUtil.String.Name, length);
- NullableType returnType = (NullableType) typeByTypeOfName[key];
- if (returnType == null)
+ IType returnType;
+ if (!typeByTypeOfName.TryGetValue(key, out returnType))
{
returnType = new StringType(SqlTypeFactory.GetString(length));
AddToTypeOfNameWithLength(key, returnType);
}
- return returnType;
+ return (NullableType)returnType;
}
- /// <summary>
- ///
- /// </summary>
- /// <param name="length"></param>
- /// <returns></returns>
+ [MethodImpl(MethodImplOptions.Synchronized)]
public static NullableType GetTypeType(int length)
{
string key = GetKeyForLengthBased(typeof(TypeType).FullName, length);
- NullableType returnType = (NullableType) typeByTypeOfName[key];
- if (returnType == null)
+ IType returnType;
+ if (!typeByTypeOfName.TryGetValue(key, out returnType))
{
returnType = new TypeType(SqlTypeFactory.GetString(length));
AddToTypeOfNameWithLength(key, returnType);
}
- return returnType;
+ return (NullableType)returnType;
}
// Association Types
Modified: trunk/nhibernate/src/NHibernate.Test/TypesTest/TypeFactoryFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/TypesTest/TypeFactoryFixture.cs 2008-08-16 06:10:38 UTC (rev 3709)
+++ trunk/nhibernate/src/NHibernate.Test/TypesTest/TypeFactoryFixture.cs 2008-08-16 07:02:48 UTC (rev 3710)
@@ -1,5 +1,4 @@
using System;
-using System.Threading;
using log4net;
using log4net.Repository.Hierarchy;
using NHibernate.Type;
@@ -79,6 +78,8 @@
[Test, Explicit]
public void MultiThreadAccess()
{
+ // Test added for NH-1251
+ // If one thread break the test you can see the result in the console.
((Logger) log.Logger).Level = log4net.Core.Level.Debug;
MultiThreadRunner<object>.ExecuteAction[] actions = new MultiThreadRunner<object>.ExecuteAction[]
{
@@ -108,7 +109,6 @@
mtr.TimeoutBetweenThreadStart = 2;
mtr.Run(null);
log.DebugFormat("{0} calls", totalCall);
- TypeFactory.GetTypeType(rnd.Next());
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-08-18 14:20:58
|
Revision: 3715
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3715&view=rev
Author: fabiomaulo
Date: 2008-08-18 14:21:05 +0000 (Mon, 18 Aug 2008)
Log Message:
-----------
Partial support of lazy="extra" (collections)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/CollectionBinder.cs
trunk/nhibernate/src/NHibernate/Collection/PersistentSet.cs
trunk/nhibernate/src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs
trunk/nhibernate/src/NHibernate/Persister/Collection/BasicCollectionPersister.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/Extralazy/
trunk/nhibernate/src/NHibernate.Test/Extralazy/Document.cs
trunk/nhibernate/src/NHibernate.Test/Extralazy/ExtraLazyFixture.cs
trunk/nhibernate/src/NHibernate.Test/Extralazy/Group.cs
trunk/nhibernate/src/NHibernate.Test/Extralazy/SessionAttribute.cs
trunk/nhibernate/src/NHibernate.Test/Extralazy/User.cs
trunk/nhibernate/src/NHibernate.Test/Extralazy/UserGroup.hbm.xml
Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/CollectionBinder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/CollectionBinder.cs 2008-08-18 13:38:05 UTC (rev 3714)
+++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/CollectionBinder.cs 2008-08-18 14:21:05 UTC (rev 3715)
@@ -167,7 +167,12 @@
// LAZINESS
InitLaziness(node, model, "true", mappings.DefaultLazy);
- // TODO: H3.1 - lazy="extra"
+ XmlAttribute lazyNode = node.Attributes["lazy"];
+ if (lazyNode != null && "extra".Equals(lazyNode.Value))
+ {
+ model.IsLazy = true;
+ model.ExtraLazy = true;
+ }
XmlNode oneToManyNode = node.SelectSingleNode(HbmConstants.nsOneToMany, namespaceManager);
if (oneToManyNode != null)
@@ -507,7 +512,7 @@
string name = subnode.LocalName; //.Name;
- if ("index".Equals(name))
+ if ("index".Equals(name) || "map-key".Equals(name))
{
SimpleValue value = new SimpleValue(model.CollectionTable);
BindSimpleValue(subnode, value, model.IsOneToMany, IndexedCollection.DefaultIndexColumnName);
@@ -515,13 +520,13 @@
if (model.Index.Type == null)
throw new MappingException("map index element must specify a type: " + model.Role);
}
- else if ("index-many-to-many".Equals(name))
+ else if ("index-many-to-many".Equals(name) || "map-key-many-to-many".Equals(name))
{
ManyToOne mto = new ManyToOne(model.CollectionTable);
BindManyToOne(subnode, mto, IndexedCollection.DefaultIndexColumnName, model.IsOneToMany);
model.Index = mto;
}
- else if ("composite-index".Equals(name))
+ else if ("composite-index".Equals(name) || "composite-map-key".Equals(name))
{
Component component = new Component(model);
BindComponent(subnode, component, null, model.Role, "index", model.IsOneToMany);
Modified: trunk/nhibernate/src/NHibernate/Collection/PersistentSet.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Collection/PersistentSet.cs 2008-08-18 13:38:05 UTC (rev 3714)
+++ trunk/nhibernate/src/NHibernate/Collection/PersistentSet.cs 2008-08-18 14:21:05 UTC (rev 3715)
@@ -385,8 +385,7 @@
if (!exists.HasValue)
{
Initialize(true);
- bool contained = set.Remove(o);
- if (contained)
+ if (set.Remove(o))
{
Dirty();
return true;
Modified: trunk/nhibernate/src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs 2008-08-18 13:38:05 UTC (rev 3714)
+++ trunk/nhibernate/src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs 2008-08-18 14:21:05 UTC (rev 3715)
@@ -1443,7 +1443,7 @@
IDataReader rs = null;
try
{
- KeyType.NullSafeSet(st, key, 1, session);
+ KeyType.NullSafeSet(st, key, 0, session);
rs = session.Batcher.ExecuteReader(st);
return rs.Read() ? rs.GetInt32(0) - baseIndex : 0;
}
@@ -1481,8 +1481,8 @@
IDataReader rs = null;
try
{
- KeyType.NullSafeSet(st, key, 1, session);
- indexOrElementType.NullSafeSet(st, indexOrElement, keyColumnNames.Length + 1, session);
+ KeyType.NullSafeSet(st, key, 0, session);
+ indexOrElementType.NullSafeSet(st, indexOrElement, keyColumnNames.Length, session);
rs = session.Batcher.ExecuteReader(st);
try
{
@@ -1520,8 +1520,8 @@
IDataReader rs = null;
try
{
- KeyType.NullSafeSet(st, key, 1, session);
- IndexType.NullSafeSet(st, IncrementIndexByBase(index), keyColumnNames.Length + 1, session);
+ KeyType.NullSafeSet(st, key, 0, session);
+ IndexType.NullSafeSet(st, IncrementIndexByBase(index), keyColumnNames.Length, session);
rs = session.Batcher.ExecuteReader(st);
try
{
Modified: trunk/nhibernate/src/NHibernate/Persister/Collection/BasicCollectionPersister.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Persister/Collection/BasicCollectionPersister.cs 2008-08-18 13:38:05 UTC (rev 3714)
+++ trunk/nhibernate/src/NHibernate/Persister/Collection/BasicCollectionPersister.cs 2008-08-18 14:21:05 UTC (rev 3715)
@@ -74,13 +74,13 @@
insert.AddColumns(new string[] {IdentifierColumnName}, null, IdentifierType);
if (HasIndex)
- insert.AddColumns(IndexColumnNames, null, IndexType);
+ insert.AddColumns(IndexColumnNames, indexColumnIsSettable, IndexType);
- insert.AddColumns(ElementColumnNames, elementColumnIsSettable, ElementType);
-
if (Factory.Settings.IsCommentsEnabled)
insert.SetComment("insert collection row " + Role);
+ insert.AddColumns(ElementColumnNames, elementColumnIsSettable, ElementType);
+
return insert.ToSqlCommandInfo();
}
Added: trunk/nhibernate/src/NHibernate.Test/Extralazy/Document.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Extralazy/Document.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Extralazy/Document.cs 2008-08-18 14:21:05 UTC (rev 3715)
@@ -0,0 +1,34 @@
+namespace NHibernate.Test.Extralazy
+{
+ public class Document
+ {
+ private string title;
+ private string content;
+ private User owner;
+ protected Document() {}
+ public Document(string title, string content, User owner)
+ {
+ this.title = title;
+ this.content = content;
+ this.owner = owner;
+ }
+
+ public virtual string Title
+ {
+ get { return title; }
+ set { title = value; }
+ }
+
+ public virtual string Content
+ {
+ get { return content; }
+ set { content = value; }
+ }
+
+ public virtual User Owner
+ {
+ get { return owner; }
+ set { owner = value; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Extralazy/ExtraLazyFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Extralazy/ExtraLazyFixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Extralazy/ExtraLazyFixture.cs 2008-08-18 14:21:05 UTC (rev 3715)
@@ -0,0 +1,232 @@
+using System.Collections;
+using NUnit.Framework;
+using NUnit.Framework.SyntaxHelpers;
+
+namespace NHibernate.Test.Extralazy
+{
+ [TestFixture]
+ public class ExtraLazyFixture : TestCase
+ {
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override IList Mappings
+ {
+ get { return new string[] {"Extralazy.UserGroup.hbm.xml"}; }
+ }
+
+ protected override string CacheConcurrencyStrategy
+ {
+ get { return null; }
+ }
+
+ [Test, Ignore("Not supported yet") ]
+ public void OrphanDelete()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+ User gavin = new User("gavin", "secret");
+ Document hia = new Document("HiA", "blah blah blah", gavin);
+ Document hia2 = new Document("HiA2", "blah blah blah blah", gavin);
+ gavin.Documents.Add(hia); // NH: added ; I don't understand how can work in H3.2.5 without add
+ gavin.Documents.Add(hia2);// NH: added
+ s.Persist(gavin);
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ gavin = s.Get<User>("gavin");
+ Assert.AreEqual(2, gavin.Documents.Count);
+ gavin.Documents.Remove(hia2);
+ Assert.IsFalse(gavin.Documents.Contains(hia2));
+ Assert.IsTrue(gavin.Documents.Contains(hia));
+ Assert.AreEqual(1, gavin.Documents.Count);
+ Assert.IsFalse(NHibernateUtil.IsInitialized(gavin.Documents));
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ gavin = s.Get<User>("gavin");
+ Assert.AreEqual(1, gavin.Documents.Count);
+ Assert.IsFalse(gavin.Documents.Contains(hia2));
+ Assert.IsTrue(gavin.Documents.Contains(hia));
+ Assert.IsFalse(NHibernateUtil.IsInitialized(gavin.Documents));
+ Assert.That(s.Get<Document>("HiA2"), Is.Null);
+ gavin.Documents.Clear();
+ Assert.IsTrue(NHibernateUtil.IsInitialized(gavin.Documents));
+ s.Delete(gavin);
+ t.Commit();
+ s.Close();
+ }
+
+ [Test]
+ public void Get()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+ User gavin = new User("gavin", "secret");
+ User turin = new User("turin", "tiger");
+ Group g = new Group("developers");
+ g.Users.Add("gavin", gavin);
+ g.Users.Add("turin", turin);
+ s.Persist(g);
+ gavin.Session.Add("foo", new SessionAttribute("foo", "foo bar baz"));
+ gavin.Session.Add("bar", new SessionAttribute("bar", "foo bar baz 2"));
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ g = s.Get<Group>("developers");
+ gavin = (User) g.Users["gavin"];
+ turin = (User) g.Users["turin"];
+ Assert.That(gavin, Is.Not.Null);
+ Assert.That(turin, Is.Not.Null);
+ Assert.That(g.Users["emmanuel"], Is.Null);
+ Assert.IsFalse(NHibernateUtil.IsInitialized(g.Users));
+ Assert.That(gavin.Session["foo"], Is.Not.Null);
+ Assert.That(turin.Session["foo"], Is.Null);
+ Assert.IsFalse(NHibernateUtil.IsInitialized(gavin.Session));
+ Assert.IsFalse(NHibernateUtil.IsInitialized(turin.Session));
+ s.Delete(gavin);
+ s.Delete(turin);
+ s.Delete(g);
+ t.Commit();
+ s.Close();
+ }
+
+ [Test]
+ public void RemoveClear()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+ User gavin = new User("gavin", "secret");
+ User turin = new User("turin", "tiger");
+ Group g = new Group("developers");
+ g.Users.Add("gavin", gavin);
+ g.Users.Add("turin", turin);
+ s.Persist(g);
+ gavin.Session.Add("foo", new SessionAttribute("foo", "foo bar baz"));
+ gavin.Session.Add("bar", new SessionAttribute("bar", "foo bar baz 2"));
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ g = s.Get<Group>("developers");
+ gavin = (User) g.Users["gavin"];
+ turin = (User) g.Users["turin"];
+ Assert.IsFalse(NHibernateUtil.IsInitialized(g.Users));
+ g.Users.Clear();
+ gavin.Session.Remove("foo");
+ Assert.IsTrue(NHibernateUtil.IsInitialized(g.Users));
+ Assert.IsTrue(NHibernateUtil.IsInitialized(gavin.Session));
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ g = s.Get<Group>("developers");
+ //Assert.IsTrue( g.Users.IsEmpty() );
+ //Assert.IsFalse( NHibernateUtil.IsInitialized( g.getUsers() ) );
+ gavin = s.Get<User>("gavin");
+ Assert.IsFalse(gavin.Session.Contains("foo"));
+ Assert.IsFalse(NHibernateUtil.IsInitialized(gavin.Session));
+ s.Delete(gavin);
+ s.Delete(turin);
+ s.Delete(g);
+ t.Commit();
+ s.Close();
+ }
+
+ [Test, Ignore("Not supported yet")]
+ public void IndexFormulaMap()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+ User gavin = new User("gavin", "secret");
+ User turin = new User("turin", "tiger");
+ Group g = new Group("developers");
+ g.Users.Add("gavin", gavin);
+ g.Users.Add("turin", turin);
+ s.Persist(g);
+ gavin.Session.Add("foo", new SessionAttribute("foo", "foo bar baz"));
+ gavin.Session.Add("bar", new SessionAttribute("bar", "foo bar baz 2"));
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ g = s.Get<Group>("developers");
+ Assert.AreEqual(2, g.Users.Count);
+ g.Users.Remove("turin");
+ IDictionary smap = ((User) g.Users["gavin"]).Session;
+ Assert.AreEqual(2, smap.Count);
+ smap.Remove("bar");
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ g = s.Get<Group>("developers");
+ Assert.AreEqual(1, g.Users.Count);
+ smap = ((User) g.Users["gavin"]).Session;
+ Assert.AreEqual(1, smap.Count);
+ g.Users["gavin"]= turin;
+ gavin = (User) g.Users["gavin"];
+ s.Delete(gavin);
+ Assert.AreEqual(0, s.CreateQuery("select count(*) from SessionAttribute").UniqueResult<long>());
+ t.Commit();
+ s.Close();
+
+ s = OpenSession();
+ t = s.BeginTransaction();
+ g = s.Get<Group>("developers");
+ Assert.AreEqual(1, g.Users.Count);
+ turin = (User) g.Users["turin"];
+ smap = turin.Session;
+ Assert.AreEqual(0, smap.Count);
+ Assert.AreEqual(1L, s.CreateQuery("select count(*) from User").UniqueResult<long>());
+ s.Delete(g);
+ s.Delete(turin);
+ Assert.AreEqual(0, s.CreateQuery("select count(*) from User").UniqueResult<long>());
+ t.Commit();
+ s.Close();
+ }
+
+ [Test]
+ public void SQLQuery()
+ {
+ ISession s = OpenSession();
+ ITransaction t = s.BeginTransaction();
+ User gavin = new User("gavin", "secret");
+ User turin = new User("turin", "tiger");
+ gavin.Session.Add("foo", new SessionAttribute("foo", "foo bar baz"));
+ gavin.Session.Add("bar", new SessionAttribute("bar", "foo bar baz 2"));
+ s.Persist(gavin);
+ s.Persist(turin);
+ s.Flush();
+ s.Clear();
+
+ IList results = s.GetNamedQuery("UserSessionData").SetParameter("uname", "%in").List();
+ Assert.AreEqual(2, results.Count);
+ gavin = (User) ((object[]) results[0])[0];
+ Assert.AreEqual("gavin", gavin.Name);
+ Assert.AreEqual(2, gavin.Session.Count);
+ t.Commit();
+ s.Close();
+
+ using (s = OpenSession())
+ using (t= s.BeginTransaction())
+ {
+ s.Delete("from SessionAttribute");
+ s.Delete("from User");
+ t.Commit();
+ }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Extralazy/Group.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Extralazy/Group.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Extralazy/Group.cs 2008-08-18 14:21:05 UTC (rev 3715)
@@ -0,0 +1,27 @@
+using System.Collections;
+
+namespace NHibernate.Test.Extralazy
+{
+ public class Group
+ {
+ private string name;
+ private IDictionary users = new Hashtable();
+ protected Group() {}
+ public Group(string name)
+ {
+ this.name = name;
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual IDictionary Users
+ {
+ get { return users; }
+ set { users = value; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Extralazy/SessionAttribute.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Extralazy/SessionAttribute.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Extralazy/SessionAttribute.cs 2008-08-18 14:21:05 UTC (rev 3715)
@@ -0,0 +1,42 @@
+namespace NHibernate.Test.Extralazy
+{
+ public class SessionAttribute
+ {
+#pragma warning disable 169
+ private long id;
+#pragma warning restore 169
+ private string name;
+ private string stringData;
+ private object objectData;
+ protected SessionAttribute() {}
+ public SessionAttribute(string name, string stringData)
+ {
+ this.name = name;
+ this.stringData = stringData;
+ }
+
+ public SessionAttribute(string name, object objectData)
+ {
+ this.name = name;
+ this.objectData = objectData;
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual string StringData
+ {
+ get { return stringData; }
+ set { stringData = value; }
+ }
+
+ public virtual object ObjectData
+ {
+ get { return objectData; }
+ set { objectData = value; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Extralazy/User.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Extralazy/User.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Extralazy/User.cs 2008-08-18 14:21:05 UTC (rev 3715)
@@ -0,0 +1,43 @@
+using System.Collections;
+using Iesi.Collections;
+
+namespace NHibernate.Test.Extralazy
+{
+ public class User
+ {
+ private string name;
+ private string password;
+ private IDictionary session = new Hashtable();
+ private ISet documents = new HashedSet();
+ protected User() {}
+ public User(string name, string password)
+ {
+ this.name = name;
+ this.password = password;
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual string Password
+ {
+ get { return password; }
+ set { password = value; }
+ }
+
+ public virtual IDictionary Session
+ {
+ get { return session; }
+ set { session = value; }
+ }
+
+ public virtual ISet Documents
+ {
+ get { return documents; }
+ set { documents = value; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Extralazy/UserGroup.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Extralazy/UserGroup.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Extralazy/UserGroup.hbm.xml 2008-08-18 14:21:05 UTC (rev 3715)
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.Extralazy">
+
+ <class name="Group" table="groups">
+ <id name="Name"/>
+ <map name="Users" cascade="persist" table="group_user" lazy="extra">
+ <key column="groupName"/>
+ <map-key formula="lower(personName)" type="string"/>
+ <many-to-many class="User" column="personName"/>
+ </map>
+ </class>
+
+ <class name="User" table="users">
+ <id name="Name"/>
+ <property name="Password"/>
+ <map name="Session" lazy="extra" cascade="persist,save-update,delete,delete-orphan">
+ <key column="userName"/> <!--Need to investigate not-null="true"-->
+ <map-key column="name" type="string"/>
+ <one-to-many class="SessionAttribute"/>
+ </map>
+ <set name="Documents" inverse="true" lazy="extra" cascade="all,delete-orphan">
+ <key column="owner"/>
+ <one-to-many class="Document"/>
+ </set>
+ </class>
+
+ <class name="Document" table="documents">
+ <id name="Title"/>
+ <property name="Content" type="string" length="10000"/>
+ <many-to-one name="Owner" not-null="true"/>
+ </class>
+
+ <class name="SessionAttribute" table="session_attributes">
+ <id name="id" access="field">
+ <generator class="native"/>
+ </id>
+ <property name="Name" update="false"/> <!--Need to investigate not-null="true"-->
+ <property name="StringData"/>
+ <property name="ObjectData" type="Serializable"/>
+ </class>
+ <!--
+ NH the map of SessionAttribute in H3.2.6 have insert="false" for property "Name" but it can't work with not-null="true"
+ We remove the inconsistence.
+ -->
+
+ <sql-query name="UserSessionData">
+ <return alias="u" class="User"/>
+ <return-join alias="s" property="u.Session"/>
+ select
+ lower(u.name) as {u.Name}, lower(u.password) as {u.Password},
+ lower(s.userName) as {s.key}, lower(s.name) as {s.index}, s.id as {s.element},
+ {s.element.*}
+ from users u
+ join session_attributes s on lower(s.userName) = lower(u.name)
+ where u.name like :uname
+ </sql-query>
+
+
+</hibernate-mapping>
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-08-18 13:38:05 UTC (rev 3714)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-08-18 14:21:05 UTC (rev 3715)
@@ -173,6 +173,11 @@
<Compile Include="ExpressionTest\SQLExpressionFixture.cs" />
<Compile Include="ExpressionTest\SubQueries\Classes.cs" />
<Compile Include="ExpressionTest\SubQueries\SubQueriesSqlFixture.cs" />
+ <Compile Include="Extralazy\Document.cs" />
+ <Compile Include="Extralazy\ExtraLazyFixture.cs" />
+ <Compile Include="Extralazy\Group.cs" />
+ <Compile Include="Extralazy\SessionAttribute.cs" />
+ <Compile Include="Extralazy\User.cs" />
<Compile Include="FilterTest\BinaryFiltered.cs" />
<Compile Include="FilterTest\Category.cs" />
<Compile Include="FilterTest\Department.cs" />
@@ -1410,6 +1415,7 @@
<EmbeddedResource Include="CompositeId\Order.hbm.xml" />
<EmbeddedResource Include="CompositeId\Product.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="Extralazy\UserGroup.hbm.xml" />
<EmbeddedResource Include="Naturalid\Immutable\User.hbm.xml" />
<EmbeddedResource Include="Naturalid\Mutable\User.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1419\Mappings.hbm.xml" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-08-18 17:27:01
|
Revision: 3717
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3717&view=rev
Author: fabiomaulo
Date: 2008-08-18 17:27:06 +0000 (Mon, 18 Aug 2008)
Log Message:
-----------
Support of lazy="extra" on air
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/CollectionBinder.cs
trunk/nhibernate/src/NHibernate/Engine/Cascade.cs
trunk/nhibernate/src/NHibernate.Test/Extralazy/ExtraLazyFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/CollectionBinder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/CollectionBinder.cs 2008-08-18 14:29:49 UTC (rev 3716)
+++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/CollectionBinder.cs 2008-08-18 17:27:06 UTC (rev 3717)
@@ -225,7 +225,7 @@
//ORPHAN DELETE (used for programmer error detection)
XmlAttribute cascadeAtt = node.Attributes["cascade"];
- if (cascadeAtt != null && cascadeAtt.Value.Equals("all-delete-orphan"))
+ if (cascadeAtt != null && cascadeAtt.Value.IndexOf("delete-orphan") >= 0)
model.HasOrphanDelete = true;
bool? isGeneric = null;
Modified: trunk/nhibernate/src/NHibernate/Engine/Cascade.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/Cascade.cs 2008-08-18 14:29:49 UTC (rev 3716)
+++ trunk/nhibernate/src/NHibernate/Engine/Cascade.cs 2008-08-18 17:27:06 UTC (rev 3717)
@@ -262,7 +262,7 @@
}
else
{
- orphans = CollectionHelper.EmptyCollection; // TODO NH: H3.2 Different pc.GetQueuedOrphans(entityName);
+ orphans = pc.GetQueuedOrphans(entityName);
}
foreach (object orphan in orphans)
Modified: trunk/nhibernate/src/NHibernate.Test/Extralazy/ExtraLazyFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Extralazy/ExtraLazyFixture.cs 2008-08-18 14:29:49 UTC (rev 3716)
+++ trunk/nhibernate/src/NHibernate.Test/Extralazy/ExtraLazyFixture.cs 2008-08-18 17:27:06 UTC (rev 3717)
@@ -22,7 +22,7 @@
get { return null; }
}
- [Test, Ignore("Not supported yet") ]
+ [Test]
public void OrphanDelete()
{
ISession s = OpenSession();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2008-08-19 13:23:24
|
Revision: 3720
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3720&view=rev
Author: fabiomaulo
Date: 2008-08-19 13:23:30 +0000 (Tue, 19 Aug 2008)
Log Message:
-----------
Start porting of new events
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs
trunk/nhibernate/src/NHibernate/Cfg/ConfigurationSchema/CfgXmlHelper.cs
trunk/nhibernate/src/NHibernate/Engine/IPersistenceContext.cs
trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs
trunk/nhibernate/src/NHibernate/Event/EventListeners.cs
trunk/nhibernate/src/NHibernate/Event/InitializeCollectionEvent.cs
trunk/nhibernate/src/NHibernate/Event/ListenerType.cs
trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj
trunk/nhibernate/src/NHibernate/Type/CollectionType.cs
trunk/nhibernate/src/NHibernate/nhibernate-configuration.xsd
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Event/AbstractCollectionEvent.cs
trunk/nhibernate/src/NHibernate/Event/IPostCollectionRecreateEventListener.cs
trunk/nhibernate/src/NHibernate/Event/IPostCollectionRemoveEventListener.cs
trunk/nhibernate/src/NHibernate/Event/IPostCollectionUpdateEventListener.cs
trunk/nhibernate/src/NHibernate/Event/IPreCollectionRecreateEventListener.cs
trunk/nhibernate/src/NHibernate/Event/IPreCollectionRemoveEventListener.cs
trunk/nhibernate/src/NHibernate/Event/IPreCollectionUpdateEventListener.cs
trunk/nhibernate/src/NHibernate/Event/PostCollectionRecreateEvent.cs
trunk/nhibernate/src/NHibernate/Event/PostCollectionRemoveEvent.cs
trunk/nhibernate/src/NHibernate/Event/PostCollectionUpdateEvent.cs
trunk/nhibernate/src/NHibernate/Event/PreCollectionRecreateEvent.cs
trunk/nhibernate/src/NHibernate/Event/PreCollectionRemoveEvent.cs
trunk/nhibernate/src/NHibernate/Event/PreCollectionUpdateEvent.cs
trunk/nhibernate/src/NHibernate.Test/Events/
Modified: trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2008-08-18 19:58:38 UTC (rev 3719)
+++ trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2008-08-19 13:23:30 UTC (rev 3720)
@@ -1666,93 +1666,110 @@
private void ClearListeners(ListenerType type)
{
-
switch (type)
{
case ListenerType.Autoflush:
- eventListeners.AutoFlushEventListeners = new IAutoFlushEventListener[] { };
+ eventListeners.AutoFlushEventListeners = new IAutoFlushEventListener[] {};
break;
case ListenerType.Merge:
- eventListeners.MergeEventListeners = new IMergeEventListener[] { };
+ eventListeners.MergeEventListeners = new IMergeEventListener[] {};
break;
case ListenerType.Create:
- eventListeners.PersistEventListeners = new IPersistEventListener[] { };
+ eventListeners.PersistEventListeners = new IPersistEventListener[] {};
break;
case ListenerType.CreateOnFlush:
- eventListeners.PersistOnFlushEventListeners = new IPersistEventListener[] { };
+ eventListeners.PersistOnFlushEventListeners = new IPersistEventListener[] {};
break;
case ListenerType.Delete:
- eventListeners.DeleteEventListeners = new IDeleteEventListener[] { };
+ eventListeners.DeleteEventListeners = new IDeleteEventListener[] {};
break;
case ListenerType.DirtyCheck:
- eventListeners.DirtyCheckEventListeners = new IDirtyCheckEventListener[] { };
+ eventListeners.DirtyCheckEventListeners = new IDirtyCheckEventListener[] {};
break;
case ListenerType.Evict:
- eventListeners.EvictEventListeners = new IEvictEventListener[] { };
+ eventListeners.EvictEventListeners = new IEvictEventListener[] {};
break;
case ListenerType.Flush:
- eventListeners.FlushEventListeners = new IFlushEventListener[] { };
+ eventListeners.FlushEventListeners = new IFlushEventListener[] {};
break;
case ListenerType.FlushEntity:
- eventListeners.FlushEntityEventListeners = new IFlushEntityEventListener[] { };
+ eventListeners.FlushEntityEventListeners = new IFlushEntityEventListener[] {};
break;
case ListenerType.Load:
- eventListeners.LoadEventListeners = new ILoadEventListener[] { };
+ eventListeners.LoadEventListeners = new ILoadEventListener[] {};
break;
case ListenerType.LoadCollection:
- eventListeners.InitializeCollectionEventListeners = new IInitializeCollectionEventListener[] { };
+ eventListeners.InitializeCollectionEventListeners = new IInitializeCollectionEventListener[] {};
break;
case ListenerType.Lock:
- eventListeners.LockEventListeners = new ILockEventListener[] { };
+ eventListeners.LockEventListeners = new ILockEventListener[] {};
break;
case ListenerType.Refresh:
- eventListeners.RefreshEventListeners = new IRefreshEventListener[] { };
+ eventListeners.RefreshEventListeners = new IRefreshEventListener[] {};
break;
case ListenerType.Replicate:
- eventListeners.ReplicateEventListeners = new IReplicateEventListener[] { };
+ eventListeners.ReplicateEventListeners = new IReplicateEventListener[] {};
break;
case ListenerType.SaveUpdate:
- eventListeners.SaveOrUpdateEventListeners = new ISaveOrUpdateEventListener[] { };
+ eventListeners.SaveOrUpdateEventListeners = new ISaveOrUpdateEventListener[] {};
break;
case ListenerType.Save:
- eventListeners.SaveEventListeners = new ISaveOrUpdateEventListener[] { };
+ eventListeners.SaveEventListeners = new ISaveOrUpdateEventListener[] {};
break;
case ListenerType.PreUpdate:
- eventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] { };
+ eventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] {};
break;
case ListenerType.Update:
- eventListeners.UpdateEventListeners = new ISaveOrUpdateEventListener[] { };
+ eventListeners.UpdateEventListeners = new ISaveOrUpdateEventListener[] {};
break;
case ListenerType.PreLoad:
- eventListeners.PreLoadEventListeners = new IPreLoadEventListener[] { };
+ eventListeners.PreLoadEventListeners = new IPreLoadEventListener[] {};
break;
case ListenerType.PreDelete:
- eventListeners.PreDeleteEventListeners = new IPreDeleteEventListener[] { };
+ eventListeners.PreDeleteEventListeners = new IPreDeleteEventListener[] {};
break;
case ListenerType.PreInsert:
- eventListeners.PreInsertEventListeners = new IPreInsertEventListener[] { };
+ eventListeners.PreInsertEventListeners = new IPreInsertEventListener[] {};
break;
case ListenerType.PostLoad:
- eventListeners.PostLoadEventListeners = new IPostLoadEventListener[] { };
+ eventListeners.PostLoadEventListeners = new IPostLoadEventListener[] {};
break;
case ListenerType.PostInsert:
- eventListeners.PostInsertEventListeners = new IPostInsertEventListener[] { };
+ eventListeners.PostInsertEventListeners = new IPostInsertEventListener[] {};
break;
case ListenerType.PostUpdate:
- eventListeners.PostUpdateEventListeners = new IPostUpdateEventListener[] { };
+ eventListeners.PostUpdateEventListeners = new IPostUpdateEventListener[] {};
break;
case ListenerType.PostDelete:
- eventListeners.PostDeleteEventListeners = new IPostDeleteEventListener[] { };
+ eventListeners.PostDeleteEventListeners = new IPostDeleteEventListener[] {};
break;
case ListenerType.PostCommitUpdate:
- eventListeners.PostCommitUpdateEventListeners = new IPostUpdateEventListener[] { };
+ eventListeners.PostCommitUpdateEventListeners = new IPostUpdateEventListener[] {};
break;
case ListenerType.PostCommitInsert:
- eventListeners.PostCommitInsertEventListeners = new IPostInsertEventListener[] { };
+ eventListeners.PostCommitInsertEventListeners = new IPostInsertEventListener[] {};
break;
case ListenerType.PostCommitDelete:
- eventListeners.PostCommitDeleteEventListeners = new IPostDeleteEventListener[] { };
+ eventListeners.PostCommitDeleteEventListeners = new IPostDeleteEventListener[] {};
break;
+ case ListenerType.PreCollectionRecreate:
+ eventListeners.PreCollectionRecreateEventListeners = new IPreCollectionRecreateEventListener[] {};
+ break;
+ case ListenerType.PreCollectionRemove:
+ eventListeners.PreCollectionRemoveEventListeners = new IPreCollectionRemoveEventListener[] {};
+ break;
+ case ListenerType.PreCollectionUpdate:
+ eventListeners.PreCollectionUpdateEventListeners = new IPreCollectionUpdateEventListener[] {};
+ break;
+ case ListenerType.PostCollectionRecreate:
+ eventListeners.PostCollectionRecreateEventListeners = new IPostCollectionRecreateEventListener[] {};
+ break;
+ case ListenerType.PostCollectionRemove:
+ eventListeners.PostCollectionRemoveEventListeners = new IPostCollectionRemoveEventListener[] {};
+ break;
+ case ListenerType.PostCollectionUpdate:
+ eventListeners.PostCollectionUpdateEventListeners = new IPostCollectionUpdateEventListener[] {};
+ break;
default:
log.Warn("Unrecognized listener type [" + type + "]");
break;
@@ -1856,6 +1873,24 @@
case ListenerType.PostCommitDelete:
eventListeners.PostCommitDeleteEventListeners = (IPostDeleteEventListener[])listeners;
break;
+ case ListenerType.PreCollectionRecreate:
+ eventListeners.PreCollectionRecreateEventListeners = (IPreCollectionRecreateEventListener[])listeners;
+ break;
+ case ListenerType.PreCollectionRemove:
+ eventListeners.PreCollectionRemoveEventListeners = (IPreCollectionRemoveEventListener[])listeners;
+ break;
+ case ListenerType.PreCollectionUpdate:
+ eventListeners.PreCollectionUpdateEventListeners = (IPreCollectionUpdateEventListener[])listeners;
+ break;
+ case ListenerType.PostCollectionRecreate:
+ eventListeners.PostCollectionRecreateEventListeners = (IPostCollectionRecreateEventListener[])listeners;
+ break;
+ case ListenerType.PostCollectionRemove:
+ eventListeners.PostCollectionRemoveEventListeners = (IPostCollectionRemoveEventListener[])listeners;
+ break;
+ case ListenerType.PostCollectionUpdate:
+ eventListeners.PostCollectionUpdateEventListeners = (IPostCollectionUpdateEventListener[])listeners;
+ break;
default:
log.Warn("Unrecognized listener type [" + type + "]");
break;
Modified: trunk/nhibernate/src/NHibernate/Cfg/ConfigurationSchema/CfgXmlHelper.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/ConfigurationSchema/CfgXmlHelper.cs 2008-08-18 19:58:38 UTC (rev 3719)
+++ trunk/nhibernate/src/NHibernate/Cfg/ConfigurationSchema/CfgXmlHelper.cs 2008-08-19 13:23:30 UTC (rev 3720)
@@ -254,6 +254,18 @@
return ListenerType.PostCommitInsert;
case "post-commit-delete":
return ListenerType.PostCommitDelete;
+ case "pre-collection-recreate":
+ return ListenerType.PreCollectionRecreate;
+ case "pre-collection-remove":
+ return ListenerType.PreCollectionRemove;
+ case "pre-collection-update":
+ return ListenerType.PreCollectionUpdate;
+ case "post-collection-recreate":
+ return ListenerType.PostCollectionRecreate;
+ case "post-collection-remove":
+ return ListenerType.PostCollectionRemove;
+ case "post-collection-update":
+ return ListenerType.PostCollectionUpdate;
default:
throw new HibernateConfigException(string.Format("Invalid ListenerType value:{0}", listenerType));
}
@@ -319,6 +331,18 @@
return "post-commit-insert";
case ListenerType.PostCommitDelete:
return "post-commit-delete";
+ case ListenerType.PreCollectionRecreate:
+ return "pre-collection-recreate";
+ case ListenerType.PreCollectionRemove:
+ return "pre-collection-remove";
+ case ListenerType.PreCollectionUpdate:
+ return "pre-collection-update";
+ case ListenerType.PostCollectionRecreate:
+ return "post-collection-recreate";
+ case ListenerType.PostCollectionRemove:
+ return "post-collection-remove";
+ case ListenerType.PostCollectionUpdate:
+ return "post-collection-update";
default:
return string.Empty;
}
Modified: trunk/nhibernate/src/NHibernate/Engine/IPersistenceContext.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/IPersistenceContext.cs 2008-08-18 19:58:38 UTC (rev 3719)
+++ trunk/nhibernate/src/NHibernate/Engine/IPersistenceContext.cs 2008-08-19 13:23:30 UTC (rev 3720)
@@ -226,6 +226,19 @@
/// <summary> Get the entity that owns this persistent collection</summary>
object GetCollectionOwner(object key, ICollectionPersister collectionPersister);
+ /// <summary> Get the entity that owned this persistent collection when it was loaded </summary>
+ /// <param name="collection">The persistent collection </param>
+ /// <returns>
+ /// The owner if its entity ID is available from the collection's loaded key
+ /// and the owner entity is in the persistence context; otherwise, returns null
+ /// </returns>
+ object GetLoadedCollectionOwnerOrNull(IPersistentCollection collection);
+
+ /// <summary> Get the ID for the entity that owned this persistent collection when it was loaded </summary>
+ /// <param name="collection">The persistent collection </param>
+ /// <returns> the owner ID if available from the collection's loaded key; otherwise, returns null </returns>
+ object GetLoadedCollectionOwnerIdOrNull(IPersistentCollection collection);
+
/// <summary> add a collection we just loaded up (still needs initializing)</summary>
void AddUninitializedCollection(ICollectionPersister persister, IPersistentCollection collection, object id);
Modified: trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs 2008-08-18 19:58:38 UTC (rev 3719)
+++ trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs 2008-08-19 13:23:30 UTC (rev 3720)
@@ -80,16 +80,16 @@
// yet loaded ... for now, this is purely transient!
private Dictionary<CollectionKey, IPersistentCollection> unownedCollections;
- private bool hasNonReadOnlyEntities = false;
+ private bool hasNonReadOnlyEntities;
[NonSerialized]
- private int cascading = 0;
+ private int cascading;
[NonSerialized]
- private bool flushing = false;
+ private bool flushing;
[NonSerialized]
- private int loadCounter = 0;
+ private int loadCounter;
[NonSerialized]
private LoadContexts loadContexts;
@@ -101,6 +101,9 @@
/// <param name="session">The session "owning" this context. </param>
public StatefulPersistenceContext(ISessionImplementor session)
{
+ loadCounter = 0;
+ flushing = false;
+ cascading = 0;
this.session = session;
entitiesByKey = new Dictionary<EntityKey, object>(InitCollectionSize);
@@ -761,6 +764,52 @@
return GetEntity(new EntityKey(key, collectionPersister.OwnerEntityPersister, session.EntityMode));
}
+ /// <summary> Get the entity that owned this persistent collection when it was loaded </summary>
+ /// <param name="collection">The persistent collection </param>
+ /// <returns>
+ /// The owner, if its entity ID is available from the collection's loaded key
+ /// and the owner entity is in the persistence context; otherwise, returns null
+ /// </returns>
+ public virtual object GetLoadedCollectionOwnerOrNull(IPersistentCollection collection)
+ {
+ CollectionEntry ce = GetCollectionEntry(collection);
+ if (ce.LoadedPersister == null)
+ {
+ return null; // early exit...
+ }
+ object loadedOwner = null;
+ // TODO: an alternative is to check if the owner has changed; if it hasn't then
+ // return collection.getOwner()
+ object entityId = GetLoadedCollectionOwnerIdOrNull(ce);
+ if (entityId != null)
+ {
+ loadedOwner = GetCollectionOwner(entityId, ce.LoadedPersister);
+ }
+ return loadedOwner;
+ }
+
+ /// <summary> Get the ID for the entity that owned this persistent collection when it was loaded </summary>
+ /// <param name="collection">The persistent collection </param>
+ /// <returns> the owner ID if available from the collection's loaded key; otherwise, returns null </returns>
+ public virtual object GetLoadedCollectionOwnerIdOrNull(IPersistentCollection collection)
+ {
+ return GetLoadedCollectionOwnerIdOrNull(GetCollectionEntry(collection));
+ }
+
+ /// <summary> Get the ID for the entity that owned this persistent collection when it was loaded </summary>
+ /// <param name="ce">The collection entry </param>
+ /// <returns> the owner ID if available from the collection's loaded key; otherwise, returns null </returns>
+ private object GetLoadedCollectionOwnerIdOrNull(CollectionEntry ce)
+ {
+ if (ce == null || ce.LoadedKey == null || ce.LoadedPersister == null)
+ {
+ return null;
+ }
+ // TODO: an alternative is to check if the owner has changed; if it hasn't then
+ // get the ID from collection.getOwner()
+ return ce.LoadedPersister.CollectionType.GetIdOfOwnerOrNull(ce.LoadedKey, session);
+ }
+
/// <summary> add a collection we just loaded up (still needs initializing)</summary>
public void AddUninitializedCollection(ICollectionPersister persister, IPersistentCollection collection, object id)
{
@@ -1159,6 +1208,9 @@
#region ISerializable Members
internal StatefulPersistenceContext(SerializationInfo info, StreamingContext context)
{
+ loadCounter = 0;
+ flushing = false;
+ cascading = 0;
entitiesByKey = (Dictionary<EntityKey, object>)info.GetValue("context.entitiesByKey", typeof(Dictionary<EntityKey, object>));
entitiesByUniqueKey = (Dictionary<EntityUniqueKey, object>)info.GetValue("context.entitiesByUniqueKey", typeof(Dictionary<EntityUniqueKey, object>));
entityEntries = (IdentityMap)info.GetValue("context.entityEntries", typeof(IdentityMap));
Added: trunk/nhibernate/src/NHibernate/Event/AbstractCollectionEvent.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Event/AbstractCollectionEvent.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Event/AbstractCollectionEvent.cs 2008-08-19 13:23:30 UTC (rev 3720)
@@ -0,0 +1,111 @@
+using System;
+using NHibernate.Collection;
+using NHibernate.Engine;
+using NHibernate.Persister.Collection;
+
+namespace NHibernate.Event
+{
+ /// <summary> Defines a base class for events involving collections. </summary>
+ [Serializable]
+ public abstract class AbstractCollectionEvent : AbstractEvent
+ {
+ private readonly object affectedOwner;
+ private readonly string affectedOwnerEntityName;
+ private readonly object affectedOwnerId;
+ private readonly IPersistentCollection collection;
+
+ /// <summary> Constructs an AbstractCollectionEvent object. </summary>
+ /// <param name="collectionPersister">The collection persister.</param>
+ /// <param name="collection">The collection </param>
+ /// <param name="source">The Session source </param>
+ /// <param name="affectedOwner">The owner that is affected by this event; can be null if unavailable </param>
+ /// <param name="affectedOwnerId">
+ /// The ID for the owner that is affected by this event; can be null if unavailable
+ /// that is affected by this event; can be null if unavailable
+ /// </param>
+ protected AbstractCollectionEvent(ICollectionPersister collectionPersister, IPersistentCollection collection,
+ IEventSource source, object affectedOwner, object affectedOwnerId) : base(source)
+ {
+ this.collection = collection;
+ this.affectedOwner = affectedOwner;
+ this.affectedOwnerId = affectedOwnerId;
+ affectedOwnerEntityName = GetAffectedOwnerEntityName(collectionPersister, affectedOwner, source);
+ }
+
+ public IPersistentCollection Collection
+ {
+ get { return collection; }
+ }
+
+ /// <summary> The collection owner entity that is affected by this event. </summary>
+ /// <value>
+ /// Returns null if the entity is not in the persistence context
+ /// (e.g., because the collection from a detached entity was moved to a new owner)
+ /// </value>
+ public object AffectedOwnerOrNull
+ {
+ get { return affectedOwner; }
+ }
+
+ /// <summary> Get the ID for the collection owner entity that is affected by this event. </summary>
+ /// <value>
+ /// Returns null if the ID cannot be obtained
+ /// from the collection's loaded key (e.g., a property-ref is used for the
+ /// collection and does not include the entity's ID)
+ /// </value>
+ public object AffectedOwnerIdOrNull
+ {
+ get { return affectedOwnerId; }
+ }
+
+ protected static ICollectionPersister GetLoadedCollectionPersister(IPersistentCollection collection,
+ IEventSource source)
+ {
+ CollectionEntry ce = source.PersistenceContext.GetCollectionEntry(collection);
+ return (ce == null ? null : ce.LoadedPersister);
+ }
+
+ protected static object GetLoadedOwnerOrNull(IPersistentCollection collection, IEventSource source)
+ {
+ return source.PersistenceContext.GetLoadedCollectionOwnerOrNull(collection);
+ }
+
+ protected static object GetLoadedOwnerIdOrNull(IPersistentCollection collection, IEventSource source)
+ {
+ return source.PersistenceContext.GetLoadedCollectionOwnerIdOrNull(collection);
+ }
+
+ protected static object GetOwnerIdOrNull(object owner, IEventSource source)
+ {
+ EntityEntry ownerEntry = source.PersistenceContext.GetEntry(owner);
+ return (ownerEntry == null ? null : ownerEntry.Id);
+ }
+
+ protected static string GetAffectedOwnerEntityName(ICollectionPersister collectionPersister, object affectedOwner,
+ IEventSource source)
+ {
+ // collectionPersister should not be null, but we don't want to throw
+ // an exception if it is null
+ string entityName = (collectionPersister == null ? null : collectionPersister.OwnerEntityPersister.EntityName);
+ if (affectedOwner != null)
+ {
+ EntityEntry ee = source.PersistenceContext.GetEntry(affectedOwner);
+ if (ee != null && ee.EntityName != null)
+ {
+ entityName = ee.EntityName;
+ }
+ }
+ return entityName;
+ }
+
+ /// <summary> Get the entity name for the collection owner entity that is affected by this event. </summary>
+ /// <returns>
+ /// The entity name; if the owner is not in the PersistenceContext, the
+ /// returned value may be a superclass name, instead of the actual class name
+ /// </returns>
+ public virtual string GetAffectedOwnerEntityName()
+ {
+ return affectedOwnerEntityName;
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Event/EventListeners.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Event/EventListeners.cs 2008-08-18 19:58:38 UTC (rev 3719)
+++ trunk/nhibernate/src/NHibernate/Event/EventListeners.cs 2008-08-19 13:23:30 UTC (rev 3720)
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using NHibernate.Cfg;
using NHibernate.Event.Default;
+using NHibernate.Util;
namespace NHibernate.Event
{
@@ -13,71 +14,127 @@
{
private static readonly IDictionary<ListenerType, System.Type> eventInterfaceFromType =
new Dictionary<ListenerType, System.Type>(28);
+
static EventListeners()
{
- eventInterfaceFromType[ListenerType.Autoflush] = typeof(IAutoFlushEventListener);
- eventInterfaceFromType[ListenerType.Merge] = typeof(IMergeEventListener);
- eventInterfaceFromType[ListenerType.Create] = typeof(IPersistEventListener);
- eventInterfaceFromType[ListenerType.CreateOnFlush] = typeof(IPersistEventListener);
- eventInterfaceFromType[ListenerType.Delete] = typeof(IDeleteEventListener);
- eventInterfaceFromType[ListenerType.DirtyCheck] = typeof(IDirtyCheckEventListener);
- eventInterfaceFromType[ListenerType.Evict] = typeof(IEvictEventListener);
- eventInterfaceFromType[ListenerType.Flush] = typeof(IFlushEventListener);
- eventInterfaceFromType[ListenerType.FlushEntity] = typeof(IFlushEntityEventListener);
- eventInterfaceFromType[ListenerType.Load] = typeof(ILoadEventListener);
- eventInterfaceFromType[ListenerType.LoadCollection] = typeof(IInitializeCollectionEventListener);
- eventInterfaceFromType[ListenerType.Lock] = typeof(ILockEventListener);
- eventInterfaceFromType[ListenerType.Refresh] = typeof(IRefreshEventListener);
- eventInterfaceFromType[ListenerType.Replicate] = typeof(IReplicateEventListener);
- eventInterfaceFromType[ListenerType.SaveUpdate] = typeof(ISaveOrUpdateEventListener);
- eventInterfaceFromType[ListenerType.Save] = typeof(ISaveOrUpdateEventListener);
- eventInterfaceFromType[ListenerType.Update] = typeof(ISaveOrUpdateEventListener);
- eventInterfaceFromType[ListenerType.PreLoad] = typeof(IPreLoadEventListener);
- eventInterfaceFromType[ListenerType.PreUpdate] = typeof(IPreUpdateEventListener);
- eventInterfaceFromType[ListenerType.PreDelete] = typeof(IPreDeleteEventListener);
- eventInterfaceFromType[ListenerType.PreInsert] = typeof(IPreInsertEventListener);
- eventInterfaceFromType[ListenerType.PostLoad] = typeof(IPostLoadEventListener);
- eventInterfaceFromType[ListenerType.PostUpdate] = typeof(IPostUpdateEventListener);
- eventInterfaceFromType[ListenerType.PostDelete] = typeof(IPostDeleteEventListener);
- eventInterfaceFromType[ListenerType.PostInsert] = typeof(IPostInsertEventListener);
- eventInterfaceFromType[ListenerType.PostCommitUpdate] = typeof(IPostUpdateEventListener);
- eventInterfaceFromType[ListenerType.PostCommitDelete] = typeof(IPostDeleteEventListener);
- eventInterfaceFromType[ListenerType.PostCommitInsert] = typeof(IPostInsertEventListener);
+ eventInterfaceFromType[ListenerType.Autoflush] = typeof (IAutoFlushEventListener);
+ eventInterfaceFromType[ListenerType.Merge] = typeof (IMergeEventListener);
+ eventInterfaceFromType[ListenerType.Create] = typeof (IPersistEventListener);
+ eventInterfaceFromType[ListenerType.CreateOnFlush] = typeof (IPersistEventListener);
+ eventInterfaceFromType[ListenerType.Delete] = typeof (IDeleteEventListener);
+ eventInterfaceFromType[ListenerType.DirtyCheck] = typeof (IDirtyCheckEventListener);
+ eventInterfaceFromType[ListenerType.Evict] = typeof (IEvictEventListener);
+ eventInterfaceFromType[ListenerType.Flush] = typeof (IFlushEventListener);
+ eventInterfaceFromType[ListenerType.FlushEntity] = typeof (IFlushEntityEventListener);
+ eventInterfaceFromType[ListenerType.Load] = typeof (ILoadEventListener);
+ eventInterfaceFromType[ListenerType.LoadCollection] = typeof (IInitializeCollectionEventListener);
+ eventInterfaceFromType[ListenerType.Lock] = typeof (ILockEventListener);
+ eventInterfaceFromType[ListenerType.Refresh] = typeof (IRefreshEventListener);
+ eventInterfaceFromType[ListenerType.Replicate] = typeof (IReplicateEventListener);
+ eventInterfaceFromType[ListenerType.SaveUpdate] = typeof (ISaveOrUpdateEventListener);
+ eventInterfaceFromType[ListenerType.Save] = typeof (ISaveOrUpdateEventListener);
+ eventInterfaceFromType[ListenerType.Update] = typeof (ISaveOrUpdateEventListener);
+ eventInterfaceFromType[ListenerType.PreLoad] = typeof (IPreLoadEventListener);
+ eventInterfaceFromType[ListenerType.PreUpdate] = typeof (IPreUpdateEventListener);
+ eventInterfaceFromType[ListenerType.PreDelete] = typeof (IPreDeleteEventListener);
+ eventInterfaceFromType[ListenerType.PreInsert] = typeof (IPreInsertEventListener);
+ eventInterfaceFromType[ListenerType.PreCollectionRecreate] = typeof (IPreCollectionRecreateEventListener);
+ eventInterfaceFromType[ListenerType.PreCollectionRemove] = typeof (IPreCollectionRemoveEventListener);
+ eventInterfaceFromType[ListenerType.PreCollectionUpdate] = typeof (IPreCollectionUpdateEventListener);
+ eventInterfaceFromType[ListenerType.PostLoad] = typeof (IPostLoadEventListener);
+ eventInterfaceFromType[ListenerType.PostUpdate] = typeof (IPostUpdateEventListener);
+ eventInterfaceFromType[ListenerType.PostDelete] = typeof (IPostDeleteEventListener);
+ eventInterfaceFromType[ListenerType.PostInsert] = typeof (IPostInsertEventListener);
+ eventInterfaceFromType[ListenerType.PostCommitUpdate] = typeof (IPostUpdateEventListener);
+ eventInterfaceFromType[ListenerType.PostCommitDelete] = typeof (IPostDeleteEventListener);
+ eventInterfaceFromType[ListenerType.PostCommitInsert] = typeof (IPostInsertEventListener);
+ eventInterfaceFromType[ListenerType.PostCollectionRecreate] = typeof (IPostCollectionRecreateEventListener);
+ eventInterfaceFromType[ListenerType.PostCollectionRemove] = typeof (IPostCollectionRemoveEventListener);
+ eventInterfaceFromType[ListenerType.PostCollectionUpdate] = typeof (IPostCollectionUpdateEventListener);
+ eventInterfaceFromType = new UnmodifiableDictionary<ListenerType, System.Type>(eventInterfaceFromType);
}
- private ILoadEventListener[] loadEventListeners = new ILoadEventListener[] { new DefaultLoadEventListener() };
- private ISaveOrUpdateEventListener[] saveOrUpdateEventListeners = new ISaveOrUpdateEventListener[] { new DefaultSaveOrUpdateEventListener() };
- private IMergeEventListener[] mergeEventListeners = new IMergeEventListener[] { new DefaultMergeEventListener() };
- private IPersistEventListener[] persistEventListeners = new IPersistEventListener[] { new DefaultPersistEventListener() };
- private IPersistEventListener[] persistOnFlushEventListeners = new IPersistEventListener[] { new DefaultPersistOnFlushEventListener() };
- private IReplicateEventListener[] replicateEventListeners = new IReplicateEventListener[] { new DefaultReplicateEventListener() };
- private IDeleteEventListener[] deleteEventListeners = new IDeleteEventListener[] { new DefaultDeleteEventListener() };
- private IAutoFlushEventListener[] autoFlushEventListeners = new IAutoFlu...
[truncated message content] |
|
From: <fab...@us...> - 2008-08-20 20:07:49
|
Revision: 3721
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3721&view=rev
Author: fabiomaulo
Date: 2008-08-20 20:07:55 +0000 (Wed, 20 Aug 2008)
Log Message:
-----------
End porting of new events for collections (need some "more" investigation of tests for ManyToMany)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Action/CollectionRecreateAction.cs
trunk/nhibernate/src/NHibernate/Action/CollectionRemoveAction.cs
trunk/nhibernate/src/NHibernate/Action/CollectionUpdateAction.cs
trunk/nhibernate/src/NHibernate/Event/Default/ReattachVisitor.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/Events/Collections/
trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractParentWithCollection.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/AbstractAssociationCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManyBagToSetCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManyBagToSetMapping.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManySetToSetCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManySetToSetMapping.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/ChildWithBidirectionalManyToMany.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/ParentWithBidirectionalManyToMany.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManyBagCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManyBagMapping.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManyBagSubclassCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManyBagSubclassMapping.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManySetCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManySetMapping.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/ChildWithManyToOne.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/ParentWithBidirectionalOneToMany.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/ParentWithBidirectionalOneToManySubclass.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/ManyToMany/
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/ManyToMany/UnidirectionalManyToManyBagCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/ManyToMany/UnidirectionalManyToManyBagMapping.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/OneToMany/
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/OneToMany/UnidirectionalOneToManyBagCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/OneToMany/UnidirectionalOneToManyBagMapping.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/OneToMany/UnidirectionalOneToManySetCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/OneToMany/UnidirectionalOneToManySetMapping.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/ParentWithCollectionOfEntities.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/ChildEntity.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/ChildValue.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/CollectionListeners.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/IChild.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/IEntity.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/IParentWithCollection.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Values/
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Values/ParentWithCollectionOfValues.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Values/ValuesBagCollectionEventFixture.cs
trunk/nhibernate/src/NHibernate.Test/Events/Collections/Values/ValuesBagMapping.hbm.xml
Modified: trunk/nhibernate/src/NHibernate/Action/CollectionRecreateAction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Action/CollectionRecreateAction.cs 2008-08-19 13:23:30 UTC (rev 3720)
+++ trunk/nhibernate/src/NHibernate/Action/CollectionRecreateAction.cs 2008-08-20 20:07:55 UTC (rev 3721)
@@ -1,6 +1,7 @@
using System;
using NHibernate.Collection;
using NHibernate.Engine;
+using NHibernate.Event;
using NHibernate.Persister.Collection;
namespace NHibernate.Action
@@ -16,16 +17,46 @@
{
IPersistentCollection collection = Collection;
+ PreRecreate();
+
Persister.Recreate(collection, Key, Session);
Session.PersistenceContext.GetCollectionEntry(collection).AfterAction(collection);
Evict();
+ PostRecreate();
+
if (Session.Factory.Statistics.IsStatisticsEnabled)
{
Session.Factory.StatisticsImplementor.RecreateCollection(Persister.Role);
}
}
+
+ private void PreRecreate()
+ {
+ IPreCollectionRecreateEventListener[] preListeners = Session.Listeners.PreCollectionRecreateEventListeners;
+ if (preListeners.Length > 0)
+ {
+ PreCollectionRecreateEvent preEvent = new PreCollectionRecreateEvent(Persister, Collection, (IEventSource)Session);
+ for (int i = 0; i < preListeners.Length; i++)
+ {
+ preListeners[i].OnPreRecreateCollection(preEvent);
+ }
+ }
+ }
+
+ private void PostRecreate()
+ {
+ IPostCollectionRecreateEventListener[] postListeners = Session.Listeners.PostCollectionRecreateEventListeners;
+ if (postListeners.Length > 0)
+ {
+ PostCollectionRecreateEvent postEvent = new PostCollectionRecreateEvent(Persister, Collection, (IEventSource)Session);
+ for (int i = 0; i < postListeners.Length; i++)
+ {
+ postListeners[i].OnPostRecreateCollection(postEvent);
+ }
+ }
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Action/CollectionRemoveAction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Action/CollectionRemoveAction.cs 2008-08-19 13:23:30 UTC (rev 3720)
+++ trunk/nhibernate/src/NHibernate/Action/CollectionRemoveAction.cs 2008-08-20 20:07:55 UTC (rev 3721)
@@ -1,26 +1,67 @@
using System;
using NHibernate.Collection;
using NHibernate.Engine;
+using NHibernate.Event;
using NHibernate.Persister.Collection;
namespace NHibernate.Action
{
[Serializable]
- public sealed class CollectionRemoveAction : CollectionAction
+ public sealed class CollectionRemoveAction : CollectionAction
{
private readonly bool emptySnapshot;
+ private readonly object affectedOwner;
- public CollectionRemoveAction(IPersistentCollection collection, ICollectionPersister persister,
- object key, bool emptySnapshot, ISessionImplementor session)
- : base(persister, collection, key, session)
+ /// <summary>
+ /// Removes a persistent collection from its loaded owner.
+ /// </summary>
+ /// <param name="collection">The collection to to remove; must be non-null </param>
+ /// <param name="persister"> The collection's persister </param>
+ /// <param name="id">The collection key </param>
+ /// <param name="emptySnapshot">Indicates if the snapshot is empty </param>
+ /// <param name="session">The session </param>
+ /// <remarks>Use this constructor when the collection is non-null.</remarks>
+ public CollectionRemoveAction(IPersistentCollection collection, ICollectionPersister persister, object id,
+ bool emptySnapshot, ISessionImplementor session)
+ : base(persister, collection, id, session)
{
+ if (collection == null)
+ {
+ throw new AssertionFailure("collection == null");
+ }
+
this.emptySnapshot = emptySnapshot;
+ affectedOwner = session.PersistenceContext.GetLoadedCollectionOwnerOrNull(collection);
}
+ /// <summary>
+ /// Removes a persistent collection from a specified owner.
+ /// </summary>
+ /// <param name="affectedOwner">The collection's owner; must be non-null </param>
+ /// <param name="persister"> The collection's persister </param>
+ /// <param name="id">The collection key </param>
+ /// <param name="emptySnapshot">Indicates if the snapshot is empty </param>
+ /// <param name="session">The session </param>
+ /// <remarks> Use this constructor when the collection to be removed has not been loaded. </remarks>
+ public CollectionRemoveAction(object affectedOwner, ICollectionPersister persister, object id, bool emptySnapshot,
+ ISessionImplementor session) : base(persister, null, id, session)
+ {
+ if (affectedOwner == null)
+ {
+ throw new AssertionFailure("affectedOwner == null");
+ }
+ this.emptySnapshot = emptySnapshot;
+ this.affectedOwner = affectedOwner;
+ }
+
public override void Execute()
{
+ PreRemove();
+
if (!emptySnapshot)
+ {
Persister.Remove(Key, Session);
+ }
IPersistentCollection collection = Collection;
if (collection != null)
@@ -30,15 +71,45 @@
Evict();
+ PostRemove();
+
if (Session.Factory.Statistics.IsStatisticsEnabled)
{
Session.Factory.StatisticsImplementor.RemoveCollection(Persister.Role);
}
}
+ private void PreRemove()
+ {
+ IPreCollectionRemoveEventListener[] preListeners = Session.Listeners.PreCollectionRemoveEventListeners;
+ if (preListeners.Length > 0)
+ {
+ PreCollectionRemoveEvent preEvent = new PreCollectionRemoveEvent(Persister, Collection, (IEventSource) Session,
+ affectedOwner);
+ for (int i = 0; i < preListeners.Length; i++)
+ {
+ preListeners[i].OnPreRemoveCollection(preEvent);
+ }
+ }
+ }
+
+ private void PostRemove()
+ {
+ IPostCollectionRemoveEventListener[] postListeners = Session.Listeners.PostCollectionRemoveEventListeners;
+ if (postListeners.Length > 0)
+ {
+ PostCollectionRemoveEvent postEvent = new PostCollectionRemoveEvent(Persister, Collection, (IEventSource) Session,
+ affectedOwner);
+ for (int i = 0; i < postListeners.Length; i++)
+ {
+ postListeners[i].OnPostRemoveCollection(postEvent);
+ }
+ }
+ }
+
public override int CompareTo(CollectionAction other)
{
return 0;
}
}
-}
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Action/CollectionUpdateAction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Action/CollectionUpdateAction.cs 2008-08-19 13:23:30 UTC (rev 3720)
+++ trunk/nhibernate/src/NHibernate/Action/CollectionUpdateAction.cs 2008-08-20 20:07:55 UTC (rev 3721)
@@ -3,6 +3,7 @@
using NHibernate.Cache.Entry;
using NHibernate.Collection;
using NHibernate.Engine;
+using NHibernate.Event;
using NHibernate.Impl;
using NHibernate.Persister.Collection;
@@ -28,6 +29,8 @@
IPersistentCollection collection = Collection;
bool affectedByFilters = persister.IsAffectedByEnabledFilters(session);
+ PreUpdate();
+
if (!collection.WasInitialized)
{
if (!collection.HasQueuedOperations)
@@ -67,12 +70,40 @@
Evict();
+ PostUpdate();
+
if (Session.Factory.Statistics.IsStatisticsEnabled)
{
Session.Factory.StatisticsImplementor.UpdateCollection(Persister.Role);
}
}
+ private void PreUpdate()
+ {
+ IPreCollectionUpdateEventListener[] preListeners = Session.Listeners.PreCollectionUpdateEventListeners;
+ if (preListeners.Length > 0)
+ {
+ PreCollectionUpdateEvent preEvent = new PreCollectionUpdateEvent(Persister, Collection, (IEventSource)Session);
+ for (int i = 0; i < preListeners.Length; i++)
+ {
+ preListeners[i].OnPreUpdateCollection(preEvent);
+ }
+ }
+ }
+
+ private void PostUpdate()
+ {
+ IPostCollectionUpdateEventListener[] postListeners = Session.Listeners.PostCollectionUpdateEventListeners;
+ if (postListeners.Length > 0)
+ {
+ PostCollectionUpdateEvent postEvent = new PostCollectionUpdateEvent(Persister, Collection, (IEventSource)Session);
+ for (int i = 0; i < postListeners.Length; i++)
+ {
+ postListeners[i].OnPostUpdateCollection(postEvent);
+ }
+ }
+ }
+
public override void AfterTransactionCompletion(bool success)
{
// NH Different behavior: to support unlocking collections from the cache.(r3260)
Modified: trunk/nhibernate/src/NHibernate/Event/Default/ReattachVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Event/Default/ReattachVisitor.cs 2008-08-19 13:23:30 UTC (rev 3720)
+++ trunk/nhibernate/src/NHibernate/Event/Default/ReattachVisitor.cs 2008-08-20 20:07:55 UTC (rev 3721)
@@ -15,7 +15,7 @@
private readonly object owner;
private static readonly ILog log = LogManager.GetLogger(typeof(AbstractFlushingEventListener));
- public ReattachVisitor(IEventSource session, object ownerIdentifier, object owner)
+ protected ReattachVisitor(IEventSource session, object ownerIdentifier, object owner)
: base(session)
{
this.ownerIdentifier = ownerIdentifier;
@@ -60,7 +60,7 @@
log.Debug("collection dereferenced while transient " +
MessageHelper.InfoString(role, ownerIdentifier, source.Factory));
}
- source.ActionQueue.AddAction(new CollectionRemoveAction(null, role, collectionKey, false, source));
+ source.ActionQueue.AddAction(new CollectionRemoveAction(owner, role, collectionKey, false, source));
}
/// <summary>
Added: trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractCollectionEventFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractCollectionEventFixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractCollectionEventFixture.cs 2008-08-20 20:07:55 UTC (rev 3721)
@@ -0,0 +1,907 @@
+using System.Collections;
+using System.Collections.Generic;
+using NHibernate.Collection;
+using NHibernate.Event;
+using NHibernate.Test.Events.Collections.Association.Bidirectional.ManyToMany;
+using NUnit.Framework;
+using NUnit.Framework.SyntaxHelpers;
+
+namespace NHibernate.Test.Events.Collections
+{
+ public abstract class AbstractCollectionEventFixture : TestCase
+ {
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ public abstract IParentWithCollection CreateParent(string name);
+
+ public abstract ICollection<IChild> CreateCollection();
+
+ protected override void OnTearDown()
+ {
+ IParentWithCollection dummyParent = CreateParent("dummyParent");
+ dummyParent.NewChildren(CreateCollection());
+ IChild dummyChild = dummyParent.AddChild("dummyChild");
+
+ using (ISession s = OpenSession())
+ {
+ using (ITransaction tx = s.BeginTransaction())
+ {
+ IList children = s.CreateCriteria(dummyChild.GetType()).List();
+ IList parents = s.CreateCriteria(dummyParent.GetType()).List();
+ foreach (IParentWithCollection parent in parents)
+ {
+ parent.ClearChildren();
+ s.Delete(parent);
+ }
+ foreach (IChild child in children)
+ {
+ s.Delete(child);
+ }
+
+ tx.Commit();
+ }
+ }
+ base.OnTearDown();
+ }
+
+ [Test]
+ public void SaveParentEmptyChildren()
+ {
+ CollectionListeners listeners = new CollectionListeners(sessions);
+ IParentWithCollection parent = CreateParentWithNoChildren("parent");
+ Assert.That(parent.Children.Count, Is.EqualTo(0));
+ int index = 0;
+ CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++);
+ CheckNumberOfResults(listeners, index);
+ listeners.Clear();
+ using (ISession s = OpenSession())
+ {
+ using (ITransaction tx = s.BeginTransaction())
+ {
+ parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id);
+ tx.Commit();
+ }
+ }
+ Assert.That(parent.Children, Is.Not.Null);
+ CheckNumberOfResults(listeners, 0);
+ }
+
+ [Test]
+ public virtual void SaveParentOneChild()
+ {
+ CollectionListeners listeners = new CollectionListeners(sessions);
+ IParentWithCollection parent = CreateParentWithOneChild("parent", "child");
+ int index = 0;
+ CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++);
+ ChildWithBidirectionalManyToMany child = GetFirstChild(parent.Children) as ChildWithBidirectionalManyToMany;
+ if (child != null)
+ {
+ CheckResult(listeners, listeners.PreCollectionRecreate, child, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, child, index++);
+ }
+
+ CheckNumberOfResults(listeners, index);
+ }
+
+ [Test]
+ public void UpdateParentNullToOneChild()
+ {
+ CollectionListeners listeners = new CollectionListeners(sessions);
+ IParentWithCollection parent = CreateParentWithNullChildren("parent");
+ listeners.Clear();
+ Assert.That(parent.Children, Is.Null);
+ ISession s = OpenSession();
+ ITransaction tx = s.BeginTransaction();
+ parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id);
+ Assert.That(parent.Children, Is.Not.Null);
+ ChildWithBidirectionalManyToMany newChild = parent.AddChild("new") as ChildWithBidirectionalManyToMany;
+ tx.Commit();
+ s.Close();
+ int index = 0;
+ if (((IPersistentCollection) parent.Children).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, parent, index++);
+ }
+ CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++);
+ CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++);
+ if (newChild != null)
+ {
+ CheckResult(listeners, listeners.PreCollectionRecreate, newChild, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, newChild, index++);
+ }
+
+ CheckNumberOfResults(listeners, index);
+ }
+
+ [Test]
+ public void UpdateParentNoneToOneChild()
+ {
+ CollectionListeners listeners = new CollectionListeners(sessions);
+ IParentWithCollection parent = CreateParentWithNoChildren("parent");
+ listeners.Clear();
+ Assert.That(parent.Children.Count, Is.EqualTo(0));
+ ISession s = OpenSession();
+ ITransaction tx = s.BeginTransaction();
+ parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id);
+ ChildWithBidirectionalManyToMany newChild = parent.AddChild("new") as ChildWithBidirectionalManyToMany;
+ tx.Commit();
+ s.Close();
+ int index = 0;
+ if (((IPersistentCollection) parent.Children).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, parent, index++);
+ }
+ CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++);
+ CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++);
+ if (newChild != null)
+ {
+ CheckResult(listeners, listeners.PreCollectionRecreate, newChild, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, newChild, index++);
+ }
+
+ CheckNumberOfResults(listeners, index);
+ }
+
+ [Test]
+ public void UpdateParentOneToTwoChildren()
+ {
+ CollectionListeners listeners = new CollectionListeners(sessions);
+ IParentWithCollection parent = CreateParentWithOneChild("parent", "child");
+ Assert.That(parent.Children.Count, Is.EqualTo(1));
+ listeners.Clear();
+ ISession s = OpenSession();
+ ITransaction tx = s.BeginTransaction();
+ parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id);
+ ChildWithBidirectionalManyToMany newChild = parent.AddChild("new2") as ChildWithBidirectionalManyToMany;
+ tx.Commit();
+ s.Close();
+ int index = 0;
+ if (((IPersistentCollection) parent.Children).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, parent, index++);
+ }
+ CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++);
+ CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++);
+ if (newChild != null)
+ {
+ CheckResult(listeners, listeners.PreCollectionRecreate, newChild, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, newChild, index++);
+ }
+
+ CheckNumberOfResults(listeners, index);
+ }
+
+ [Test]
+ public void UpdateParentOneToTwoSameChildren()
+ {
+ CollectionListeners listeners = new CollectionListeners(sessions);
+ IParentWithCollection parent = CreateParentWithOneChild("parent", "child");
+ IChild child = GetFirstChild(parent.Children);
+ Assert.That(parent.Children.Count, Is.EqualTo(1));
+ listeners.Clear();
+ ISession s = OpenSession();
+ ITransaction tx = s.BeginTransaction();
+ parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id);
+ IEntity e = child as IEntity;
+ if (e != null)
+ {
+ child = (IChild) s.Get(child.GetType(), e.Id);
+ }
+ parent.AddChild(child);
+ tx.Commit();
+ s.Close();
+ int index = 0;
+ if (((IPersistentCollection) parent.Children).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, parent, index++);
+ }
+ ChildWithBidirectionalManyToMany childWithManyToMany = child as ChildWithBidirectionalManyToMany;
+ if (childWithManyToMany != null)
+ {
+ if (((IPersistentCollection) childWithManyToMany.Parents).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, childWithManyToMany, index++);
+ }
+ }
+
+ if (!(parent.Children is PersistentSet))
+ {
+ CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++);
+ CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++);
+ }
+ if (childWithManyToMany != null && !(childWithManyToMany.Parents is PersistentSet))
+ {
+ CheckResult(listeners, listeners.PreCollectionUpdate, childWithManyToMany, index++);
+ CheckResult(listeners, listeners.PostCollectionUpdate, childWithManyToMany, index++);
+ }
+
+ CheckNumberOfResults(listeners, index);
+ }
+
+ [Test]
+ public void UpdateParentNullToOneChildDiffCollection()
+ {
+ CollectionListeners listeners = new CollectionListeners(sessions);
+ IParentWithCollection parent = CreateParentWithNullChildren("parent");
+ listeners.Clear();
+ Assert.That(parent.Children, Is.Null);
+ ISession s = OpenSession();
+ ITransaction tx = s.BeginTransaction();
+ parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id);
+ ICollection<IChild> collectionOrig = parent.Children;
+ parent.NewChildren(CreateCollection());
+ ChildWithBidirectionalManyToMany newChild = parent.AddChild("new") as ChildWithBidirectionalManyToMany;
+ tx.Commit();
+ s.Close();
+ int index = 0;
+ if (((IPersistentCollection) collectionOrig).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, parent, collectionOrig, index++);
+ }
+ CheckResult(listeners, listeners.PreCollectionRemove, parent, collectionOrig, index++);
+ CheckResult(listeners, listeners.PostCollectionRemove, parent, collectionOrig, index++);
+ if (newChild != null)
+ {
+ CheckResult(listeners, listeners.PreCollectionRecreate, newChild, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, newChild, index++);
+ }
+ CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++);
+ CheckNumberOfResults(listeners, index);
+ }
+
+ [Test]
+ public void UpdateParentNoneToOneChildDiffCollection()
+ {
+ CollectionListeners listeners = new CollectionListeners(sessions);
+ IParentWithCollection parent = CreateParentWithNoChildren("parent");
+ listeners.Clear();
+ Assert.That(parent.Children.Count, Is.EqualTo(0));
+ ISession s = OpenSession();
+ ITransaction tx = s.BeginTransaction();
+ parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id);
+ ICollection<IChild> oldCollection = parent.Children;
+ parent.NewChildren(CreateCollection());
+ ChildWithBidirectionalManyToMany newChild = parent.AddChild("new") as ChildWithBidirectionalManyToMany;
+ tx.Commit();
+ s.Close();
+ int index = 0;
+ if (((IPersistentCollection) oldCollection).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, parent, oldCollection, index++);
+ }
+ CheckResult(listeners, listeners.PreCollectionRemove, parent, oldCollection, index++);
+ CheckResult(listeners, listeners.PostCollectionRemove, parent, oldCollection, index++);
+ if (newChild != null)
+ {
+ CheckResult(listeners, listeners.PreCollectionRecreate, newChild, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, newChild, index++);
+ }
+
+ CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++);
+ CheckNumberOfResults(listeners, index);
+ }
+
+ [Test]
+ public void UpdateParentOneChildDiffCollectionSameChild()
+ {
+ CollectionListeners listeners = new CollectionListeners(sessions);
+ IParentWithCollection parent = CreateParentWithOneChild("parent", "child");
+ IChild child = GetFirstChild(parent.Children);
+ listeners.Clear();
+ Assert.That(parent.Children.Count, Is.EqualTo(1));
+ ISession s = OpenSession();
+ ITransaction tx = s.BeginTransaction();
+ parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id);
+ IEntity e = child as IEntity;
+ if (e != null)
+ {
+ child = (IChild) s.Get(child.GetType(), e.Id);
+ }
+ ICollection<IChild> oldCollection = parent.Children;
+ parent.NewChildren(CreateCollection());
+ parent.AddChild(child);
+ tx.Commit();
+ s.Close();
+ int index = 0;
+ if (((IPersistentCollection) oldCollection).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, parent, oldCollection, index++);
+ }
+ ChildWithBidirectionalManyToMany childWithManyToMany = child as ChildWithBidirectionalManyToMany;
+ if (childWithManyToMany != null)
+ {
+ if (((IPersistentCollection) childWithManyToMany.Parents).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, childWithManyToMany, index++);
+ }
+ }
+
+ CheckResult(listeners, listeners.PreCollectionRemove, parent, oldCollection, index++);
+ CheckResult(listeners, listeners.PostCollectionRemove, parent, oldCollection, index++);
+ if (childWithManyToMany != null)
+ {
+ // hmmm, the same parent was removed and re-added to the child's collection;
+ // should this be considered an update?
+ CheckResult(listeners, listeners.PreCollectionUpdate, childWithManyToMany, index++);
+ CheckResult(listeners, listeners.PostCollectionUpdate, childWithManyToMany, index++);
+ }
+ CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++);
+ CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++);
+ CheckNumberOfResults(listeners, index);
+ }
+
+ [Test]
+ public void UpdateParentOneChildDiffCollectionDiffChild()
+ {
+ CollectionListeners listeners = new CollectionListeners(sessions);
+ IParentWithCollection parent = CreateParentWithOneChild("parent", "child");
+ IChild oldChild = GetFirstChild(parent.Children);
+ listeners.Clear();
+ Assert.That(parent.Children.Count, Is.EqualTo(1));
+ ISession s = OpenSession();
+ ITransaction tx = s.BeginTransaction();
+ parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id);
+ IEntity e = oldChild as IEntity;
+ ChildWithBidirectionalManyToMany oldChildWithManyToMany = null;
+ if (e != null)
+ {
+ oldChildWithManyToMany = s.Get(oldChild.GetType(), e.Id) as ChildWithBidirectionalManyToMany;
+ }
+ ICollection<IChild> oldCollection = parent.Children;
+ parent.NewChildren(CreateCollection());
+ IChild newChild = parent.AddChild("new1");
+ tx.Commit();
+ s.Close();
+ int index = 0;
+ if (((IPersistentCollection) oldCollection).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, parent, oldCollection, index++);
+ }
+ if (oldChildWithManyToMany != null)
+ {
+ if (((IPersistentCollection) oldChildWithManyToMany.Parents).WasInitialized)
+ {
+ CheckResult(listeners, listeners.InitializeCollection, oldChildWithManyToMany, index++);
+ }
+ }
+ CheckResult(listeners, listeners.PreCollectionRemove, parent, oldCollection, index++);
+ CheckResult(listeners, listeners.PostCollectionRemove, parent, oldCollection, index++);
+ if (oldChildWithManyToMany != null)
+ {
+ ...
[truncated message content] |