@@ -2014,7 +2014,63 @@ public object GetValue (object obj)
20142014 return _prop . GetValue ( obj , null ) ;
20152015 }
20162016 }
2017- }
2017+ }
2018+
2019+ internal class EnumCacheInfo
2020+ {
2021+ public EnumCacheInfo ( Type type )
2022+ {
2023+ #if ! USE_NEW_REFLECTION_API
2024+ IsEnum = type . IsEnum ;
2025+ #else
2026+ IsEnum = type . GetTypeInfo ( ) . IsEnum ;
2027+ #endif
2028+
2029+ if ( IsEnum )
2030+ {
2031+ // This is a big assumption, but for now support ints only as key, otherwise we still
2032+ // have to pay the price for boxing
2033+ EnumValues = Enum . GetValues ( type ) . Cast < int > ( ) . ToDictionary ( x => x , x => x . ToString ( ) ) ;
2034+
2035+ #if ! USE_NEW_REFLECTION_API
2036+ StoreAsText = type . GetCustomAttribute ( typeof ( StoreAsTextAttribute ) , false ) != null ;
2037+ #else
2038+ StoreAsText = type . GetTypeInfo ( ) . GetCustomAttribute ( typeof ( StoreAsTextAttribute ) , false ) != null ;
2039+ #endif
2040+ }
2041+ }
2042+
2043+ public bool IsEnum { get ; private set ; }
2044+
2045+ public bool StoreAsText { get ; private set ; }
2046+
2047+ public Dictionary < int , string > EnumValues { get ; private set ; }
2048+ }
2049+
2050+ internal static class EnumCache
2051+ {
2052+ private static readonly Dictionary < Type , EnumCacheInfo > Cache = new Dictionary < Type , EnumCacheInfo > ( ) ;
2053+
2054+ public static EnumCacheInfo GetInfo < T > ( )
2055+ {
2056+ return GetInfo ( typeof ( T ) ) ;
2057+ }
2058+
2059+ public static EnumCacheInfo GetInfo ( Type type )
2060+ {
2061+ lock ( Cache )
2062+ {
2063+ EnumCacheInfo info = null ;
2064+ if ( ! Cache . TryGetValue ( type , out info ) )
2065+ {
2066+ info = new EnumCacheInfo ( type ) ;
2067+ Cache [ type ] = info ;
2068+ }
2069+
2070+ return info ;
2071+ }
2072+ }
2073+ }
20182074
20192075 public static class Orm
20202076 {
@@ -2369,22 +2425,24 @@ internal static void BindParameter (Sqlite3Statement stmt, int index, object val
23692425 }
23702426 } else if ( value is DateTimeOffset ) {
23712427 SQLite3 . BindInt64 ( stmt , index , ( ( DateTimeOffset ) value ) . UtcTicks ) ;
2372- #if ! USE_NEW_REFLECTION_API
2373- } else if ( value . GetType ( ) . IsEnum ) {
2374- #else
2375- } else if ( value . GetType ( ) . GetTypeInfo ( ) . IsEnum ) {
2376- #endif
2377- if ( value . GetType ( ) . GetTypeInfo ( ) . GetCustomAttribute ( typeof ( StoreAsTextAttribute ) , false ) != null )
2378- SQLite3 . BindText ( stmt , index , value . ToString ( ) , - 1 , NegativePointer ) ;
2379- else
2380- SQLite3 . BindInt ( stmt , index , Convert . ToInt32 ( value ) ) ;
2381- } else if ( value is byte [ ] ) {
2382- SQLite3 . BindBlob ( stmt , index , ( byte [ ] ) value , ( ( byte [ ] ) value ) . Length , NegativePointer ) ;
2383- } else if ( value is Guid ) {
2384- SQLite3 . BindText ( stmt , index , ( ( Guid ) value ) . ToString ( ) , 72 , NegativePointer ) ;
23852428 } else {
2386- throw new NotSupportedException ( "Cannot store type: " + value . GetType ( ) ) ;
2387- }
2429+ // Now we could possibly get an enum, retrieve cached info
2430+ var valueType = value . GetType ( ) ;
2431+ var enumInfo = EnumCache . GetInfo ( valueType ) ;
2432+ if ( enumInfo . IsEnum ) {
2433+ var enumIntValue = Convert . ToInt32 ( value ) ;
2434+ if ( enumInfo . StoreAsText )
2435+ SQLite3 . BindText ( stmt , index , enumInfo . EnumValues [ enumIntValue ] , - 1 , NegativePointer ) ;
2436+ else
2437+ SQLite3 . BindInt ( stmt , index , enumIntValue ) ;
2438+ } else if ( value is byte [ ] ) {
2439+ SQLite3 . BindBlob ( stmt , index , ( byte [ ] ) value , ( ( byte [ ] ) value ) . Length , NegativePointer ) ;
2440+ } else if ( value is Guid ) {
2441+ SQLite3 . BindText ( stmt , index , ( ( Guid ) value ) . ToString ( ) , 72 , NegativePointer ) ;
2442+ } else {
2443+ throw new NotSupportedException ( "Cannot store type: " + value . GetType ( ) ) ;
2444+ }
2445+ }
23882446 }
23892447 }
23902448
0 commit comments