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;
-               }
-
     }
 }


Reply via email to