Author: gbayon
Date: Thu Jan 4 13:28:10 2007
New Revision: 492753
URL: http://svn.apache.org/viewvc?view=rev&rev=492753
Log:
- Fixed for iIBATISNET-182 : Allow lazy load on simple class
Modified:
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Account.cs
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Order.cs
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Maps/MSSQL/SqlClient/Order.xml
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/NUnit/SqlMapTests/StatementTest.cs
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectGenericListStrategy.cs
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectListStrategy.cs
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectObjectStrategy.cs
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyFactoryBuilder.cs
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadInterceptor.cs
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadProxyFactory.cs
Modified: ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Account.cs
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Account.cs?view=diff&rev=492753&r1=492752&r2=492753
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Account.cs
(original)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Account.cs Thu Jan
4 13:28:10 2007
@@ -35,7 +35,7 @@
_document = document;
}
- public int Id
+ public virtual int Id
{
get { return id; }
set { id = value; }
Modified: ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Order.cs
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Order.cs?view=diff&rev=492753&r1=492752&r2=492753
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Order.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Order.cs Thu Jan 4
13:28:10 2007
@@ -146,26 +146,14 @@
public string City
{
- get
- {
- return _city;
- }
- set
- {
- _city = value;
- }
+ get { return _city; }
+ set { _city = value; }
}
public string Street
{
- get
- {
- return _street;
- }
- set
- {
- _street = value;
- }
+ get { return _street; }
+ set { _street = value; }
}
public string CardExpiry
@@ -204,16 +192,10 @@
}
}
- public Account Account
+ public virtual Account Account
{
- get
- {
- return _account;
- }
- set
- {
- _account = value;
- }
+ get { return _account; }
+ set { _account = value; }
}
public int Id
Modified:
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Maps/MSSQL/SqlClient/Order.xml
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Maps/MSSQL/SqlClient/Order.xml?view=diff&rev=492753&r1=492752&r2=492753
==============================================================================
---
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Maps/MSSQL/SqlClient/Order.xml
(original)
+++
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Maps/MSSQL/SqlClient/Order.xml
Thu Jan 4 13:28:10 2007
@@ -151,6 +151,19 @@
<result property="Province" column="Order_Province"/>
<result property="PostalCode" column="Order_PostalCode"/>
</resultMap>
+
+ <resultMap id="order-JIRA182" class="Order" >
+ <result property="Id" column="Order_ID"/>
+ <result property="Account" column="Account_ID" lazyLoad="true"
select="GetAccountViaColumnName"/>
+ <result property="Date" column="Order_Date"/>
+ <result property="CardExpiry" column="Order_CardExpiry"/>
+ <result property="CardType" column="Order_CardType"/>
+ <result property="CardNumber" column="Order_CardNumber"/>
+ <result property="Street" column="Order_Street"/>
+ <result property="City" column="Order_City"/>
+ <result property="Province" column="Order_Province"/>
+ <result property="PostalCode" column="Order_PostalCode"/>
+ </resultMap>
<resultMap id="credit-card-result" class="string">
<result property="value" column="Order_CardNumber"/>
@@ -772,34 +785,32 @@
<select id="GetOrderConstructor8"
parameterClass="Integer"
resultMap="order-result-constructor8">
- select
- Order_ID,
- Order_Date,
- Order_CardExpiry,
- Order_CardType,
- Order_CardNumber,
- Order_Street,
- Order_City,
- Order_Province,
- Order_PostalCode,
- acc.Account_ID,
- acc.Account_FirstName,
- acc.Account_LastName,
- acc.Account_Email,
- acc.Account_Banner_Option,
- acc.Account_Cart_Option
- from Orders as ord
- LEFT OUTER JOIN Accounts as acc on acc.Account_ID =
ord.Account_ID
- where Order_ID = #value#
- </select>
-
-
+ select
+ Order_ID,
+ Order_Date,
+ Order_CardExpiry,
+ Order_CardType,
+ Order_CardNumber,
+ Order_Street,
+ Order_City,
+ Order_Province,
+ Order_PostalCode,
+ acc.Account_ID,
+ acc.Account_FirstName,
+ acc.Account_LastName,
+ acc.Account_Email,
+ acc.Account_Banner_Option,
+ acc.Account_Cart_Option
+ from Orders as ord
+ LEFT OUTER JOIN Accounts as acc on acc.Account_ID =
ord.Account_ID
+ where Order_ID = #value#
+ </select>
- <select id="GetOrderConstructor9"
- extends="GetOrderConstructor8"
- parameterClass="Integer"
- resultMap="order-joined-with-account-constructor">
- </select>
+ <select id="GetOrderConstructor9"
+ extends="GetOrderConstructor8"
+ parameterClass="Integer"
+ resultMap="order-joined-with-account-constructor">
+ </select>
<select id="GetOrderConstructor10"
parameterClass="Integer"
@@ -823,8 +834,26 @@
from Orders as ord
LEFT OUTER JOIN Accounts as acc on acc.Account_ID = ord.Account_ID
where Order_ID = #value#
- </select>
-
+ </select>
+
+ <select id="JIRA182"
+ parameterClass="Integer"
+ resultMap="order-JIRA182">
+ select
+ Order_ID,
+ Order_Date,
+ Order_CardExpiry,
+ Order_CardType,
+ Order_CardNumber,
+ Order_Street,
+ Order_City,
+ Order_Province,
+ Order_PostalCode,
+ Account_ID
+ from Orders
+ where Order_ID = #value#
+ </select>
+
</statements>
<parameterMaps>
Modified:
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/NUnit/SqlMapTests/StatementTest.cs
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/NUnit/SqlMapTests/StatementTest.cs?view=diff&rev=492753&r1=492752&r2=492753
==============================================================================
---
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/NUnit/SqlMapTests/StatementTest.cs
(original)
+++
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/NUnit/SqlMapTests/StatementTest.cs
Thu Jan 4 13:28:10 2007
@@ -1225,6 +1225,19 @@
#region JIRA Tests
/// <summary>
+ /// Test a constructor argument with select tag.
+ /// </remarks>
+ [Test]
+ public void TestJIRA182()
+ {
+ Order order = sqlMap.QueryForObject("JIRA182", 5) as Order;
+
+ Assert.IsTrue(order.Id == 5);
+ Assert.IsNotNull(order.Account);
+ Assert.AreEqual(5, order.Account.Id);
+ }
+
+ /// <summary>
/// QueryForDictionary does not process select property
/// </summary>
[Test]
Modified:
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectGenericListStrategy.cs
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectGenericListStrategy.cs?view=diff&rev=492753&r1=492752&r2=492753
==============================================================================
---
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectGenericListStrategy.cs
(original)
+++
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectGenericListStrategy.cs
Thu Jan 4 13:28:10 2007
@@ -29,7 +29,6 @@
using System.Data;
using IBatisNet.DataMapper.Configuration.ResultMapping;
-using IBatisNet.DataMapper.Proxy;
using IBatisNet.DataMapper.Scope;
namespace IBatisNet.DataMapper.MappedStatements.PropertyStrategy
Modified:
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectListStrategy.cs
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectListStrategy.cs?view=diff&rev=492753&r1=492752&r2=492753
==============================================================================
---
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectListStrategy.cs
(original)
+++
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectListStrategy.cs
Thu Jan 4 13:28:10 2007
@@ -27,7 +27,6 @@
using System.Collections;
using System.Data;
using IBatisNet.DataMapper.Configuration.ResultMapping;
-using IBatisNet.DataMapper.Proxy;
using IBatisNet.DataMapper.Scope;
namespace IBatisNet.DataMapper.MappedStatements.PropertyStrategy
Modified:
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectObjectStrategy.cs
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectObjectStrategy.cs?view=diff&rev=492753&r1=492752&r2=492753
==============================================================================
---
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectObjectStrategy.cs
(original)
+++
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/PropertStrategy/SelectObjectStrategy.cs
Thu Jan 4 13:28:10 2007
@@ -64,8 +64,16 @@
postSelect.Target = target;
postSelect.ResultProperty = mapping;
- postSelect.Method =
PostBindind.ExecuteMethod.ExecuteQueryForObject;
- request.QueueSelect.Enqueue(postSelect);
+ if (mapping.IsLazyLoad)
+ {
+ object values =
mapping.LazyFactory.CreateProxy(selectStatement, keys, target,
mapping.SetAccessor);
+ mapping.SetAccessor.Set(target, values);
+ }
+ else
+ {
+ postSelect.Method =
PostBindind.ExecuteMethod.ExecuteQueryForObject;
+ request.QueueSelect.Enqueue(postSelect);
+ }
}
/// <summary>
Modified:
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyFactoryBuilder.cs
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyFactoryBuilder.cs?view=diff&rev=492753&r1=492752&r2=492753
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyFactoryBuilder.cs
(original)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyFactoryBuilder.cs Thu
Jan 4 13:28:10 2007
@@ -38,7 +38,7 @@
/// </summary>
public class LazyFactoryBuilder
{
- IDictionary _factory = new HybridDictionary();
+ private IDictionary _factory = new HybridDictionary();
/// <summary>
/// Initializes a new instance of the <see cref="LazyFactoryBuilder"/>
class.
Modified:
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadInterceptor.cs
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadInterceptor.cs?view=diff&rev=492753&r1=492752&r2=492753
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadInterceptor.cs
(original)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadInterceptor.cs
Thu Jan 4 13:28:10 2007
@@ -31,7 +31,9 @@
using System.Reflection;
using Castle.DynamicProxy;
using IBatisNet.Common.Logging;
+using IBatisNet.Common.Utilities.Objects;
using IBatisNet.Common.Utilities.Objects.Members;
+using IBatisNet.Common.Utilities.Proxy;
using IBatisNet.DataMapper.MappedStatements;
#if dotnet2
using System.Collections.Generic;
@@ -51,10 +53,11 @@
private object _param = null;
private object _target = null;
private ISetAccessor _setAccessor= null;
- private ISqlMapper _sqlMap = null;
+ private ISqlMapper _sqlMap = null;
private string _statementName = string.Empty;
private bool _loaded = false;
- private IList _innerList = null;
+ private object _lazyLoadedItem = null;
+ //private IList _innerList = null;
private object _loadLock = new object();
private static ArrayList _passthroughMethods = new ArrayList();
@@ -69,7 +72,6 @@
static LazyLoadInterceptor()
{
_passthroughMethods.Add("GetType");
- _passthroughMethods.Add("ToString");
}
/// <summary>
@@ -80,13 +82,13 @@
/// <param name="setAccessor">The proxified member
accessor.</param>
/// <param name="target">The target object which contains the
property proxydied.</param>
internal LazyLoadInterceptor(IMappedStatement mappedSatement,
object param,
- object target, ISetAccessor setAccessor)
+ object target, ISetAccessor setAccessor)
{
_param = param;
_statementName = mappedSatement.Id;
_sqlMap = mappedSatement.SqlMap;
_target = target;
- _setAccessor = setAccessor;
+ _setAccessor = setAccessor;
}
#endregion
@@ -113,13 +115,23 @@
{
_logger.Debug("Proxyfying call,
query statement " + _statementName);
}
- _innerList =
_sqlMap.QueryForList(_statementName, _param);
+
+ //Perform load
+ if
(typeof(IList).IsAssignableFrom(_setAccessor.MemberType))
+ {
+ _lazyLoadedItem =
_sqlMap.QueryForList(_statementName, _param);
+ }
+ else
+ {
+ _lazyLoadedItem =
_sqlMap.QueryForObject(_statementName, _param);
+ }
+
_loaded = true;
- _setAccessor.Set(_target, _innerList);
+ _setAccessor.Set(_target,
_lazyLoadedItem);
}
}
- object returnValue = invocation.Method.Invoke(
_innerList, arguments);
+ object returnValue = invocation.Method.Invoke(
_lazyLoadedItem, arguments);
if (_logger.IsDebugEnabled)
{
Modified:
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadProxyFactory.cs
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadProxyFactory.cs?view=diff&rev=492753&r1=492752&r2=492753
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadProxyFactory.cs
(original)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadProxyFactory.cs
Thu Jan 4 13:28:10 2007
@@ -24,13 +24,11 @@
#endregion
using System;
-using System.Collections;
using System.Reflection;
using Castle.DynamicProxy;
using IBatisNet.Common.Logging;
using IBatisNet.Common.Utilities.Objects.Members;
using IBatisNet.Common.Utilities.Proxy;
-using IBatisNet.DataMapper.Exceptions;
using IBatisNet.DataMapper.MappedStatements;
namespace IBatisNet.DataMapper.Proxy
@@ -38,21 +36,12 @@
/// <summary>
/// This class is responsible of create lazy load proxies for a concrete
class with virtual method.
/// </summary>
- public class LazyLoadProxyFactory :ILazyFactory
+ public class LazyLoadProxyFactory : ILazyFactory
{
#region Fields
private static readonly ILog _logger = LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType );
#endregion
- #region Constructor
- /// <summary>
- /// constructor
- /// </summary>
- public LazyLoadProxyFactory()
- {
- }
- #endregion
-
#region ILazyFactory Members
/// <summary>
/// Builds the specified lazy load proxy for a concrete class
with virtual method.
@@ -65,94 +54,27 @@
public object CreateProxy(IMappedStatement selectStatement, object
param,
object target, ISetAccessor setAccessor)
{
- object proxy = null;
Type typeProxified = setAccessor.MemberType;
- //bool isIList =
typeof(IList).IsAssignableFrom(setAccessor.MemberType) ||
setAccessor.MemberType.IsSubclassOf(typeof(IList));
- //Type returnedTypeByStatement =
LazyLoadProxyFactory.GetTypeReturnedByStatemet(selectStatement, isIList);
-
- ////Test if the result of the lazy load is assigable to property,
test now load time instead
- ////wait to error when the method of proxy are called
- //if (typeProxified.IsAssignableFrom(returnedTypeByStatement) ==
false)
- //{
- // throw new DataMapperException("Error building LazyLoad proxy
for " + target.GetType() + "." + setAccessor.Name + " can not assing " +
typeProxified + " to " + returnedTypeByStatement);
- //}
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug(string.Format("Statement '{0}', create proxy for
member {1}.", selectStatement.Id, setAccessor.MemberType));
+ }
- ////Build the proxy
+ // Build the proxy
IInterceptor handler = new LazyLoadInterceptor(selectStatement,
param, target, setAccessor);
- //if (isIList)
- //{
- // if (_logger.IsDebugEnabled)
- // {
- // _logger.Debug(string.Format("Statement '{0}', create
list proxy for member {1}.", selectStatement.Id, setAccessor.MemberType));
- // }
-
- // if (selectStatement.Statement.ListClass == null)
- // {
- // proxy =
ProxyGeneratorFactory.GetProxyGenerator().CreateProxy(typeof(IList), handler,
new ArrayList());
- // }
- // else
- // {
- // if you want to proxy concrete classes, there are also
two requirements:
- // the class can not be sealed and only virtual methods
can be intercepted.
- // The reason is that DynamicProxy will create a subclass
of your class overriding all methods
- // so it can dispatch the invocations to the interceptor.
- proxy =
ProxyGeneratorFactory.GetProxyGenerator().CreateClassProxy(typeProxified,
handler, Type.EmptyTypes);
- // }
- //}
- //else
- //{
- // throw new DataMapperException(string.Format("Only proxy on
IList type are supported, the member type ({0}) cannot be proxyfied.",
typeProxified) );
- //}
+ // if you want to proxy concrete classes, there are also 2 main
requirements :
+ // the class can not be sealed and only virtual methods can be
intercepted.
+ // The reason is that DynamicProxy will create a subclass of your
class overriding all methods
+ // so it can dispatch the invocations to the interceptor.
+
+ // The proxified type must also have an empty constructor
+ object proxy =
ProxyGeneratorFactory.GetProxyGenerator().CreateClassProxy(typeProxified,
handler, Type.EmptyTypes);
+
return proxy;
}
#endregion
-
- /// <summary>
- /// Gets the type returned by statemet.
- /// </summary>
- /// <param name="mappedStatement">The mapped statement.</param>
- /// <param name="isIList">if set to <c>true</c> [is
Ilist].</param>
- /// <returns>The type object return by the statement.</returns>
- private static Type GetTypeReturnedByStatemet(IMappedStatement
mappedStatement,
- bool isIList)
- {
- Type returnedType = null;
-
- if ( isIList )
- {
- if (mappedStatement.Statement.ListClass != null)
- {
- //Strongly type collection
- returnedType =
mappedStatement.Statement.ListClass;
- }
- else
- {
- //Generic List, IList is the return
type of ExecuteQueryForList(..)
- returnedType = typeof(IList);
- }
- }
- else
- {
- //Property to proxified is a simple object
- if (mappedStatement.Statement.ResultClass !=
null)
- {
- returnedType =
mappedStatement.Statement.ResultClass;
- }
- else if (mappedStatement.Statement.ParameterMap
!= null)
- {
- returnedType =
mappedStatement.Statement.ParameterMap.Class;
- }
- else
- {
- throw new DataMapperException("We must
never get here !");
- }
- }
-
- return returnedType;
- }
-
}
}