banshee r3782 - in trunk/banshee: . src/Libraries/Hyena/Hyena.Data.Sqlite



Author: scottp
Date: Wed Apr 16 20:05:05 2008
New Revision: 3782
URL: http://svn.gnome.org/viewvc/banshee?rev=3782&view=rev

Log:
* src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs:
* src/Libraries/Hyena/Hyena.Data.Sqlite/DatabaseColumn.cs: Reverted
IL injection changes.

Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/DatabaseColumn.cs
   trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs

Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/DatabaseColumn.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/DatabaseColumn.cs	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/DatabaseColumn.cs	Wed Apr 16 20:05:05 2008
@@ -29,58 +29,28 @@
 using System;
 using System.Data;
 using System.Reflection;
-using System.Reflection.Emit;
 using System.Text;
 
 namespace Hyena.Data.Sqlite
 {
-    internal abstract class AbstractDatabaseColumn<T>
+    internal abstract class AbstractDatabaseColumn
     {
-        
-#region Dynamic Method stuff
-        
-        private delegate object GetDel (T target);
-        private delegate void SetDel (T target, IDataReader reader, int column);
-        private delegate void SetIntDel (T target, int value);
-        
-        private static readonly FieldInfo dateTimeMinValue = typeof (DateTime).GetField ("MinValue");
-        private static readonly MethodInfo dateTimeEquals = typeof (DateTime).GetMethod ("Equals", new Type[] { typeof (DateTime), typeof (DateTime) });
-        private static readonly FieldInfo timeSpanMinValue = typeof (TimeSpan).GetField ("MinValue");
-        private static readonly MethodInfo timeSpanEquals = typeof (TimeSpan).GetMethod ("Equals", new Type[] { typeof (TimeSpan), typeof (TimeSpan) });
-        private static readonly PropertyInfo timeSpanTotalMilliseconds = typeof (TimeSpan).GetProperty ("TotalMilliseconds");
-        private static readonly MethodInfo timeSpanFromMilliseconds = typeof (TimeSpan).GetMethod ("FromMilliseconds");
-        private static readonly MethodInfo fromDateTime = typeof (DateTimeUtil).GetMethod ("FromDateTime");
-        private static readonly MethodInfo toDateTime = typeof (DateTimeUtil).GetMethod ("ToDateTime");
-        private static readonly MethodInfo readerIsDbNull = typeof (IDataRecord).GetMethod ("IsDBNull");
-        private static readonly MethodInfo readerGetInt32 = typeof (IDataRecord).GetMethod ("GetInt32");
-        private static readonly MethodInfo readerGetInt64 = typeof (IDataRecord).GetMethod ("GetInt64");
-        private static readonly MethodInfo readerGetString = typeof (IDataRecord).GetMethod ("GetString");
-        
-        private GetDel get_del;
-        private GetDel get_raw_del;
-        private SetDel set_del;
-        private SetIntDel set_int_del;
-        
-#endregion
-        
         private readonly FieldInfo field_info;
         private readonly PropertyInfo property_info;
         private readonly Type type;
         private readonly string column_type;
         private readonly string name;
-        private readonly bool select;
         
         protected AbstractDatabaseColumn (FieldInfo field_info, AbstractDatabaseColumnAttribute attribute)
             : this (attribute, field_info, field_info.FieldType)
         {
             this.field_info = field_info;
-            BuildMethods ();
         }
         
         protected AbstractDatabaseColumn (PropertyInfo property_info, AbstractDatabaseColumnAttribute attribute) :
             this (attribute, property_info, property_info.PropertyType)
         {
-            if (!property_info.CanRead || (select && !property_info.CanWrite)) {
+            if (!property_info.CanRead || (attribute.Select && !property_info.CanWrite)) {
                 throw new Exception (String.Format (
                     "{0}: The property {1} must have both a get and a set " +
                     "block in order to be bound to a database column.",
@@ -89,7 +59,6 @@
                 );
             }
             this.property_info = property_info;
-            BuildMethods ();
         }
         
         private AbstractDatabaseColumn (AbstractDatabaseColumnAttribute attribute, MemberInfo member_info, Type type)
@@ -100,190 +69,31 @@
                 throw new Exception(string.Format(
                     "{0}.{1}: {3}", member_info.DeclaringType, member_info.Name, e.Message));
             }
-            this.type = type;
             this.name = attribute.ColumnName ?? member_info.Name;
-            this.select = attribute.Select;
-        }
-        
-#region Dynamic Method Construction
-        
-        private void BuildMethods ()
-        {
-            BuildGetMethod ();
-            BuildGetRawMethod ();
-            if (select) {
-                BuildSetMethod ();
-                if (type == typeof (int)) {
-                    BuildSetIntMethod ();
-                }
-            }
-        }
-        
-        private void BuildGetMethod ()
-        {
-            DynamicMethod method = new DynamicMethod (String.Format ("Get_{0}", name), typeof (object), new Type [] { typeof (T) }, typeof (T));
-            ILGenerator il = method.GetILGenerator ();
-            il.Emit (OpCodes.Ldarg_0);
-            if (field_info != null) {
-                il.Emit (OpCodes.Ldfld, field_info);
-            } else {
-                il.Emit (OpCodes.Call, property_info.GetGetMethod (true));
-            }
-            if (type == typeof (DateTime)) {
-                il.Emit (OpCodes.Dup);
-                il.Emit (OpCodes.Ldsfld, dateTimeMinValue);
-                il.Emit (OpCodes.Call, dateTimeEquals);
-                Label label = il.DefineLabel ();
-                il.Emit (OpCodes.Brfalse, label);
-                il.Emit (OpCodes.Pop);
-                il.Emit (OpCodes.Ldnull);
-                il.Emit (OpCodes.Ret);
-                il.MarkLabel (label);
-                il.Emit (OpCodes.Call, fromDateTime);
-                il.Emit (OpCodes.Box, typeof (long));
-            } else if (type == typeof (TimeSpan)) {
-                il.Emit (OpCodes.Ldsfld, timeSpanMinValue);
-                il.Emit (OpCodes.Call, timeSpanEquals);
-                Label label = il.DefineLabel ();
-                il.Emit (OpCodes.Brfalse_S, label);
-                il.Emit (OpCodes.Ldnull);
-                il.Emit (OpCodes.Ret);
-                il.MarkLabel (label);
-                if (field_info != null) {
-                    il.Emit (OpCodes.Ldarg_0);
-                    il.Emit (OpCodes.Ldflda, field_info);
-                } else {
-                    il.DeclareLocal (type);
-                    il.Emit (OpCodes.Ldarg_0);
-                    il.Emit (OpCodes.Call, property_info.GetGetMethod ());
-                    il.Emit (OpCodes.Stloc_0);
-                    il.Emit (OpCodes.Ldloca, 0);
-                }
-                il.Emit (OpCodes.Call, timeSpanTotalMilliseconds.GetGetMethod ());
-                il.Emit (OpCodes.Conv_I8);
-                il.Emit (OpCodes.Box, typeof (long));
-            } else if (type.IsEnum) {
-                il.Emit (OpCodes.Box, Enum.GetUnderlyingType (type));
-            } else if (type.IsValueType) {
-                il.Emit (OpCodes.Box, type);
-            }
-            il.Emit (OpCodes.Ret);
-            get_del = (GetDel)method.CreateDelegate (typeof (GetDel));
-        }
-        
-        private void BuildGetRawMethod ()
-        {
-            DynamicMethod method = new DynamicMethod (String.Format ("GetRaw_{0}", name), typeof (object), new Type [] { typeof (T) }, typeof (T));
-            ILGenerator il = method.GetILGenerator ();
-            il.Emit (OpCodes.Ldarg_0);
-            if (field_info != null) {
-                il.Emit (OpCodes.Ldfld, field_info);
-            } else {
-                il.Emit (OpCodes.Call, property_info.GetGetMethod (true));
-            }
-            if (type.IsValueType) {
-                il.Emit (OpCodes.Box, type);
-            }
-            il.Emit (OpCodes.Ret);
-            get_raw_del = (GetDel)method.CreateDelegate (typeof (GetDel));
-        }
-        
-        private void BuildAssignmentIL (ILGenerator il)
-        {
-            if (field_info != null) {
-                il.Emit (OpCodes.Stfld, field_info);
-            } else {
-                il.Emit (OpCodes.Call, property_info.GetSetMethod (true));
-            }
-            il.Emit (OpCodes.Ret);
-        }
-        
-        private void BuildSetMethod ()
-        {
-            DynamicMethod method = new DynamicMethod (String.Format ("Set_{0}", name), null, new Type [] { typeof (T), typeof (IDataReader), typeof (int) }, typeof (T));
-            ILGenerator il = method.GetILGenerator ();
-            il.Emit (OpCodes.Ldarg_0);
-            il.Emit (OpCodes.Ldarg_1);
-            il.Emit (OpCodes.Ldarg_2);
-            il.Emit (OpCodes.Callvirt, readerIsDbNull);
-            Label label_not_null = il.DefineLabel ();
-            il.Emit (OpCodes.Brfalse, label_not_null);
-            
-            if (type == typeof (DateTime)) {
-                il.Emit (OpCodes.Ldsfld, dateTimeMinValue);
-                Label label_end = il.DefineLabel ();
-                il.Emit (OpCodes.Br, label_end);
-                il.MarkLabel (label_not_null);
-                il.Emit (OpCodes.Ldarg_1);
-                il.Emit (OpCodes.Ldarg_2);
-                il.Emit (OpCodes.Callvirt, readerGetInt64);
-                il.Emit (OpCodes.Call, toDateTime);
-                il.MarkLabel (label_end);
-                BuildAssignmentIL (il);
-            } else if (type == typeof (TimeSpan)) {
-                il.Emit (OpCodes.Ldsfld, timeSpanMinValue);
-                Label label_end = il.DefineLabel ();
-                il.Emit (OpCodes.Br, label_end);
-                il.MarkLabel (label_not_null);
-                il.Emit (OpCodes.Ldarg_1);
-                il.Emit (OpCodes.Ldarg_2);
-                il.Emit (OpCodes.Callvirt, readerGetInt64);
-                il.Emit (OpCodes.Conv_R8);
-                il.Emit (OpCodes.Call, timeSpanFromMilliseconds);
-                il.MarkLabel (label_end);
-                BuildAssignmentIL (il);
-            } else {
-                il.Emit (OpCodes.Pop);
-                il.Emit (OpCodes.Ret);
-                il.MarkLabel (label_not_null);
-                il.Emit (OpCodes.Ldarg_1);
-                il.Emit (OpCodes.Ldarg_2);
-                MethodInfo getter = null;
-                if (type.IsValueType) {
-                    Type real_type = type.IsEnum ? Enum.GetUnderlyingType (type) : type;
-                    getter = real_type == typeof (int) ? readerGetInt32 : readerGetInt64;
-                } else {
-                    getter = readerGetString;
-                }
-                il.Emit (OpCodes.Callvirt, getter);
-                BuildAssignmentIL (il);
-            }
-            set_del = (SetDel)method.CreateDelegate (typeof (SetDel));
-        }
-        
-        private void BuildSetIntMethod ()
-        {
-            DynamicMethod method = new DynamicMethod (String.Format ("SetInt_{0}", name), null, new Type [] { typeof (T), typeof (int) }, typeof (T));
-            ILGenerator il = method.GetILGenerator ();
-            il.Emit (OpCodes.Ldarg_0);
-            il.Emit (OpCodes.Ldarg_1);
-            BuildAssignmentIL (il);
-            set_int_del = (SetIntDel)method.CreateDelegate (typeof (SetIntDel));
+            this.type = type;
         }
-        
-#endregion
 
-        public object GetRawValue (T target)
-        {
-            return get_raw_del (target);
-        }
-        
-        public object GetValue (T target)
+        public object GetRawValue (object target)
         {
-            return get_del (target);
+            return field_info != null ? field_info.GetValue (target) : property_info.GetValue (target, null);
         }
         
-        public void SetValue (T target, IDataReader reader, int column)
+        public object GetValue (object target)
         {
-            set_del (target, reader, column);
+            object result = field_info != null
+                ? field_info.GetValue (target)
+                : property_info.GetValue (target, null);
+            return SqliteUtils.ToDbFormat (type, result);
         }
         
-        public void SetIntValue (T target, int value)
+        public void SetValue (object target, IDataReader reader, int column)
         {
-            set_int_del (target, value);
+            // FIXME should we insist on nullable types?
+            object value = reader.IsDBNull (column) ? null : reader.GetValue (column);
+            SetValue (target, SqliteUtils.FromDbFormat(type, value));
         }
         
-        public void SetValue (T target, object value)
+        public void SetValue (object target, object value)
         {
             if (field_info != null) {
                 field_info.SetValue (target, value);
@@ -301,7 +111,7 @@
         }
     }
     
-    internal sealed class DatabaseColumn<T> : AbstractDatabaseColumn<T>
+    internal sealed class DatabaseColumn : AbstractDatabaseColumn
     {
         private DatabaseColumnAttribute attribute;
         
@@ -337,7 +147,7 @@
         
         public override bool Equals (object o)
         {
-            DatabaseColumn<T> column = o as DatabaseColumn<T>;
+            DatabaseColumn column = o as DatabaseColumn;
             return o != null && column.Name.Equals (Name);
         }
         
@@ -347,7 +157,7 @@
         }
     }
     
-    internal sealed class VirtualDatabaseColumn<T> : AbstractDatabaseColumn<T>
+    internal sealed class VirtualDatabaseColumn : AbstractDatabaseColumn
     {
         private VirtualDatabaseColumnAttribute attribute;
         
@@ -389,4 +199,4 @@
             DefaultValue = default_value;
         }
     }
-}
+}
\ No newline at end of file

Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs	Wed Apr 16 20:05:05 2008
@@ -36,11 +36,11 @@
 {
     public abstract class SqliteModelProvider<T>
     {
-        private readonly List<DatabaseColumn<T>> columns = new List<DatabaseColumn<T>> ();
-        private readonly List<DatabaseColumn<T>> select_columns = new List<DatabaseColumn<T>> ();
-        private readonly List<VirtualDatabaseColumn<T>> virtual_columns = new List<VirtualDatabaseColumn<T>> ();
+        private readonly List<DatabaseColumn> columns = new List<DatabaseColumn> ();
+        private readonly List<DatabaseColumn> select_columns = new List<DatabaseColumn> ();
+        private readonly List<VirtualDatabaseColumn> virtual_columns = new List<VirtualDatabaseColumn> ();
         
-        private DatabaseColumn<T> key;
+        private DatabaseColumn key;
         private HyenaSqliteConnection connection;
         
         private HyenaSqliteCommand create_command;
@@ -159,7 +159,7 @@
             //Console.WriteLine ("In {0} checking for table {1}", this, TableName);
             IDictionary<string, string> schema = connection.GetSchema (TableName);
             if (schema.Count > 0) {
-                foreach (DatabaseColumn<T> column in columns) {
+                foreach (DatabaseColumn column in columns) {
                     if (!schema.ContainsKey (column.Name)) {
                         AddColumnToTable (column.Schema);
                     }
@@ -179,11 +179,11 @@
         {
             DatabaseColumnAttribute column = attribute as DatabaseColumnAttribute;
             if (column != null) {
-                DatabaseColumn<T> c = member is FieldInfo
-                    ? new DatabaseColumn<T> ((FieldInfo)member, column)
-                    : new DatabaseColumn<T> ((PropertyInfo)member, column);
+                DatabaseColumn c = member is FieldInfo
+                    ? new DatabaseColumn ((FieldInfo)member, column)
+                    : new DatabaseColumn ((PropertyInfo)member, column);
                 
-                foreach (DatabaseColumn<T> col in columns) {
+                foreach (DatabaseColumn col in columns) {
                     if (col.Name == c.Name) {
                         throw new Exception (String.Format (
                             "{0} has multiple columns named {1}",
@@ -216,9 +216,9 @@
             VirtualDatabaseColumnAttribute virtual_column = attribute as VirtualDatabaseColumnAttribute;
             if (virtual_column != null) {
                 if (member is FieldInfo) {
-                    virtual_columns.Add (new VirtualDatabaseColumn<T> ((FieldInfo) member, virtual_column));
+                    virtual_columns.Add (new VirtualDatabaseColumn ((FieldInfo) member, virtual_column));
                 } else {
-                    virtual_columns.Add (new VirtualDatabaseColumn<T> ((PropertyInfo) member, virtual_column));
+                    virtual_columns.Add (new VirtualDatabaseColumn ((PropertyInfo) member, virtual_column));
                 }
             }
         }
@@ -226,7 +226,7 @@
         protected virtual void CreateTable ()
         {
             connection.Execute (CreateCommand);
-            foreach (DatabaseColumn<T> column in columns) {
+            foreach (DatabaseColumn column in columns) {
                 if (column.Index != null) {
                     connection.Execute (String.Format (
                         "CREATE INDEX {0} ON {1}({2})",
@@ -241,7 +241,7 @@
             if (((int)key.GetValue (target)) > 0) {
                 Update (target);
             } else {
-                key.SetIntValue (target, Insert (target));
+                key.SetValue (target, Insert (target));
             }
         }
         
@@ -297,14 +297,14 @@
         {
             int i = 0;
             
-            AbstractDatabaseColumn<T> bad_column = null;
+            AbstractDatabaseColumn bad_column = null;
             try {
-                foreach (DatabaseColumn<T> column in select_columns) {
+                foreach (DatabaseColumn column in select_columns) {
                     bad_column = column;
                     column.SetValue (target, reader, i++);
                 }
                 
-                foreach (VirtualDatabaseColumn<T> column in virtual_columns) {
+                foreach (VirtualDatabaseColumn column in virtual_columns) {
                     bad_column = column;
                     column.SetValue (target, reader, i++);
                 }
@@ -383,7 +383,7 @@
 
         public void Copy (T original, T copy)
         {
-            foreach (DatabaseColumn<T> column in select_columns) {
+            foreach (DatabaseColumn column in select_columns) {
                 if (column != key) {
                     column.SetValue (copy, column.GetRawValue (original));
                 }
@@ -398,7 +398,7 @@
                     builder.Append (TableName);
                     builder.Append ('(');
                     bool first = true;
-                    foreach (DatabaseColumn<T> column in columns) {
+                    foreach (DatabaseColumn column in columns) {
                         if (first) {
                             first = false;
                         } else {
@@ -420,7 +420,7 @@
                     StringBuilder cols = new StringBuilder ();
                     StringBuilder vals = new StringBuilder ();
                     bool first = true;
-                    foreach (DatabaseColumn<T> column in columns) {
+                    foreach (DatabaseColumn column in columns) {
                         if (column != key) {
                             if (first) {
                                 first = false;
@@ -450,7 +450,7 @@
                     builder.Append (TableName);
                     builder.Append (" SET ");
                     bool first = true;
-                    foreach (DatabaseColumn<T> column in columns) {
+                    foreach (DatabaseColumn column in columns) {
                         if (column != key) {
                             if (first) {
                                 first = false;
@@ -558,7 +558,7 @@
         {
             StringBuilder select_builder = new StringBuilder ();
             bool first = true;
-            foreach (DatabaseColumn<T> column in select_columns) {
+            foreach (DatabaseColumn column in select_columns) {
                 if (first) {
                     first = false;
                 } else {
@@ -573,7 +573,7 @@
             Dictionary<string, string> tables = new Dictionary<string,string> (virtual_columns.Count + 1);
             tables.Add (TableName, null);
             bool first_virtual = true;
-            foreach (VirtualDatabaseColumn<T> column in virtual_columns) {
+            foreach (VirtualDatabaseColumn column in virtual_columns) {
                 if (first_virtual) {
                     first_virtual = false;
                 } else {
@@ -667,4 +667,4 @@
             );
         }
 	}
-}
+}
\ No newline at end of file



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]