From ac29542f8e2604ae0dbf055ecee23b1ecab0b875 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 15 Sep 2014 10:47:34 +1000 Subject: [PATCH] Revert "Fixes PetaPoco to support Medium trust." - I'm reverting this fix so that we are back using the baseline logic of PetaPoco since we don't need med trust support and this known logic that has been working for many years. --- src/Umbraco.Core/Persistence/PetaPoco.cs | 104 +++++++++-------------- 1 file changed, 41 insertions(+), 63 deletions(-) diff --git a/src/Umbraco.Core/Persistence/PetaPoco.cs b/src/Umbraco.Core/Persistence/PetaPoco.cs index d8507ac681..56e9fecdb9 100644 --- a/src/Umbraco.Core/Persistence/PetaPoco.cs +++ b/src/Umbraco.Core/Persistence/PetaPoco.cs @@ -842,7 +842,7 @@ namespace Umbraco.Core.Persistence public IEnumerable Query(Sql sql) { return Query(new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, null, sql.SQL, sql.Arguments); } // Automagically guess the property relationships between various POCOs and create a delegate that will set them up - Delegate GetAutoMapper(Type[] types) + object GetAutoMapper(Type[] types) { // Build a key var kb = new StringBuilder(); @@ -857,7 +857,7 @@ namespace Umbraco.Core.Persistence RWLock.EnterReadLock(); try { - Delegate mapper; + object mapper; if (AutoMappers.TryGetValue(key, out mapper)) return mapper; } @@ -871,7 +871,7 @@ namespace Umbraco.Core.Persistence try { // Try again - Delegate mapper; + object mapper; if (AutoMappers.TryGetValue(key, out mapper)) return mapper; @@ -944,53 +944,22 @@ namespace Umbraco.Core.Persistence throw new InvalidOperationException(string.Format("Couldn't find split point between {0} and {1}", typeThis, typeNext)); } - // Instance data used by the Multipoco factory delegate - essentially a list of the nested poco factories to call public class MultiPocoFactory { - - public MultiPocoFactory(IEnumerable dels) - { - Delegates = new List(dels); - } - private List Delegates { get; set; } - private Delegate GetItem(int index) { return Delegates[index]; } - - /// - /// Calls the delegate at the specified index and returns its values - /// - /// - /// - /// - private object CallDelegate(int index, IDataReader reader) - { - var d = GetItem(index); - var output = d.DynamicInvoke(reader); - return output; - } - - /// - /// Calls the callback delegate and passes in the output of all delegates as the parameters - /// - /// - /// - /// - /// - /// - public TRet CallCallback(Delegate callback, IDataReader dr, int count) - { - var args = new List(); - for(var i = 0;i m_Delegates; + public Delegate GetItem(int index) { return m_Delegates[index]; } } // Create a multi-poco factory - Func CreateMultiPocoFactory(Type[] types, string sql, IDataReader r) - { + Func CreateMultiPocoFactory(Type[] types, string sql, IDataReader r) + { + var m = new DynamicMethod("petapoco_multipoco_factory", typeof(TRet), new Type[] { typeof(MultiPocoFactory), typeof(IDataReader), typeof(object) }, typeof(MultiPocoFactory)); + var il = m.GetILGenerator(); + + // Load the callback + il.Emit(OpCodes.Ldarg_2); + // Call each delegate var dels = new List(); int pos = 0; @@ -999,19 +968,33 @@ namespace Umbraco.Core.Persistence // Add to list of delegates to call var del = FindSplitPoint(types[i], i + 1 < types.Length ? types[i + 1] : null, sql, r, ref pos); dels.Add(del); + + // Get the delegate + il.Emit(OpCodes.Ldarg_0); // callback,this + il.Emit(OpCodes.Ldc_I4, i); // callback,this,Index + il.Emit(OpCodes.Callvirt, typeof(MultiPocoFactory).GetMethod("GetItem")); // callback,Delegate + il.Emit(OpCodes.Ldarg_1); // callback,delegate, datareader + + // Call Invoke + var tDelInvoke = del.GetType().GetMethod("Invoke"); + il.Emit(OpCodes.Callvirt, tDelInvoke); // Poco left on stack } - var mpFactory = new MultiPocoFactory(dels); - return (reader, arg3) => mpFactory.CallCallback(arg3, reader, types.Length); + // By now we should have the callback and the N pocos all on the stack. Call the callback and we're done + il.Emit(OpCodes.Callvirt, Expression.GetFuncType(types.Concat(new Type[] { typeof(TRet) }).ToArray()).GetMethod("Invoke")); + il.Emit(OpCodes.Ret); + + // Finish up + return (Func)m.CreateDelegate(typeof(Func), new MultiPocoFactory() { m_Delegates = dels }); } // Various cached stuff static Dictionary MultiPocoFactories = new Dictionary(); - static Dictionary AutoMappers = new Dictionary(); + static Dictionary AutoMappers = new Dictionary(); static System.Threading.ReaderWriterLockSlim RWLock = new System.Threading.ReaderWriterLockSlim(); - // Get (or create) the multi-poco factory for a query - Func GetMultiPocoFactory(Type[] types, string sql, IDataReader r) + // Get (or create) the multi-poco factory for a query + Func GetMultiPocoFactory(Type[] types, string sql, IDataReader r) { // Build a key string (this is crap, should address this at some point) var kb = new StringBuilder(); @@ -1033,10 +1016,7 @@ namespace Umbraco.Core.Persistence { object oFactory; if (MultiPocoFactories.TryGetValue(key, out oFactory)) - { - //mpFactory = oFactory; - return (Func)oFactory; - } + return (Func)oFactory; } finally { @@ -1048,17 +1028,15 @@ namespace Umbraco.Core.Persistence try { // Check again - object oFactory; ; + object oFactory; if (MultiPocoFactories.TryGetValue(key, out oFactory)) - { - return (Func)oFactory; - } - - // Create the factory - var factory = CreateMultiPocoFactory(types, sql, r); + return (Func)oFactory; - MultiPocoFactories.Add(key, factory); - return factory; + // Create the factory + var Factory = CreateMultiPocoFactory(types, sql, r); + + MultiPocoFactories.Add(key, Factory); + return Factory; } finally { @@ -1068,7 +1046,7 @@ namespace Umbraco.Core.Persistence } // Actual implementation of the multi-poco query - public IEnumerable Query(Type[] types, Delegate cb, string sql, params object[] args) + public IEnumerable Query(Type[] types, object cb, string sql, params object[] args) { OpenSharedConnection(); try