System.Data.SQLite
Check-in [c43fca0ae6]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Refactor previous commit to remove the new delegates as they are not strictly required. Also, remove superfluous newData local variable in the StepCallback method.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | logBind
Files: files | file ages | folders
SHA1: c43fca0ae614eb03eeb5238beea29adc5c3ee80e
User & Date: mistachkin 2012-02-19 08:34:17
Context
2012-02-19
13:22
When converting a DateTime instance of an 'Unspecified' kind to a string, use the same kind as the connection, if available. Also, cleanup handling of the default formats for UTC and local time. Closed-Leaf check-in: dbdf2561a4 user: mistachkin tags: logBind
08:34
Refactor previous commit to remove the new delegates as they are not strictly required. Also, remove superfluous newData local variable in the StepCallback method. check-in: c43fca0ae6 user: mistachkin tags: logBind
08:11
Make sure that exceptions are never thrown back to native code from user-provided function and collation implementations. Also, log all such caught callback exceptions if the appropriate connection flag is set. Fix for ticket [8a426d12eb]. Pass connection flags into SQLiteFunction binding method and refactor internal interfaces to support this. Change type of _contextDataList (SQLiteFunction) dictionary keys from long to IntPtr. check-in: 6136a92dc5 user: mistachkin tags: logBind
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to System.Data.SQLite/SQLiteFunction.cs.

    44     44       /// code.
    45     45       /// </summary>
    46     46       private const int COR_E_EXCEPTION = unchecked((int)0x80131500);
    47     47       #endregion
    48     48   
    49     49       /////////////////////////////////////////////////////////////////////////
    50     50   
    51         -    #region Private Delegate Types
    52         -    /// <summary>
    53         -    /// See the Invoke method of this class.
    54         -    /// </summary>
    55         -    /// <param name="args">
    56         -    /// See the Invoke method of this class.
    57         -    /// </param>
    58         -    /// <returns>
    59         -    /// See the Invoke method of this class.
    60         -    /// </returns>
    61         -    private delegate object SQLiteFunctionInvokeCallback(
    62         -        object[] args
    63         -    );
    64         -
    65         -    /////////////////////////////////////////////////////////////////////////
    66         -
    67         -    /// <summary>
    68         -    /// See the Step method of this class.
    69         -    /// </summary>
    70         -    /// <param name="args">
    71         -    /// See the Step method of this class.
    72         -    /// </param>
    73         -    /// <param name="stepNumber">
    74         -    /// See the Step method of this class.
    75         -    /// </param>
    76         -    /// <param name="contextData">
    77         -    /// See the Step method of this class.
    78         -    /// </param>
    79         -    private delegate void SQLiteFunctionStepCallback(
    80         -        object[] args,
    81         -        int stepNumber,
    82         -        ref object contextData
    83         -    );
    84         -
    85         -    /////////////////////////////////////////////////////////////////////////
    86         -
    87         -    /// <summary>
    88         -    /// See the Final method of this class.
    89         -    /// </summary>
    90         -    /// <param name="contextData">
    91         -    /// See the Final method of this class.
    92         -    /// </param>
    93         -    /// <returns>
    94         -    /// See the Final method of this class.
    95         -    /// </returns>
    96         -    private delegate object SQLiteFunctionFinalCallback(
    97         -        object contextData
    98         -    );
    99         -
   100         -    /////////////////////////////////////////////////////////////////////////
   101         -
   102         -    /// <summary>
   103         -    /// See the Compare method of this class.
   104         -    /// </summary>
   105         -    /// <param name="param1">
   106         -    /// See the Compare method of this class.
   107         -    /// </param>
   108         -    /// <param name="param2">
   109         -    /// See the Compare method of this class.
   110         -    /// </param>
   111         -    /// <returns>
   112         -    /// See the Compare method of this class.
   113         -    /// </returns>
   114         -    private delegate int SQLiteCollationCompareCallback(
   115         -        string param1,
   116         -        string param2
   117         -    );
   118         -    #endregion
   119         -
   120         -    /////////////////////////////////////////////////////////////////////////
   121         -
   122     51       /// <summary>
   123     52       /// The base connection this function is attached to
   124     53       /// </summary>
   125     54       internal SQLiteBase              _base;
   126     55   
   127     56       /// <summary>
   128     57       /// Internal array used to keep track of aggregate function context data
................................................................................
   131     60   
   132     61       /// <summary>
   133     62       /// The connection flags associated with this object (this should be the
   134     63       /// same value as the flags associated with the parent connection object).
   135     64       /// </summary>
   136     65       private SQLiteConnectionFlags _flags;
   137     66   
   138         -    /// <summary>
   139         -    /// The private instance of the SQLiteFunctionInvokeCallback delegate
   140         -    /// associated with this object.
   141         -    /// </summary>
   142         -    private SQLiteFunctionInvokeCallback _invokeCallback;
   143         -
   144         -    /// <summary>
   145         -    /// The private instance of the SQLiteFunctionStepCallback delegate
   146         -    /// associated with this object.
   147         -    /// </summary>
   148         -    private SQLiteFunctionStepCallback _stepCallback;
   149         -
   150         -    /// <summary>
   151         -    /// The private instance of the SQLiteFunctionFinalCallback delegate
   152         -    /// associated with this object.
   153         -    /// </summary>
   154         -    private SQLiteFunctionFinalCallback _finalCallback;
   155         -
   156         -    /// <summary>
   157         -    /// The private instance of the SQLiteCollationCompareCallback delegate
   158         -    /// associated with this object.
   159         -    /// </summary>
   160         -    private SQLiteCollationCompareCallback _compareCallback;
   161         -
   162     67       /// <summary>
   163     68       /// Holds a reference to the callback function for user functions
   164     69       /// </summary>
   165     70       private SQLiteCallback  _InvokeFunc;
   166     71       /// <summary>
   167     72       /// Holds a reference to the callbakc function for stepping in an aggregate function
   168     73       /// </summary>
................................................................................
   246    151                       if (disp != null)
   247    152                           disp.Dispose();
   248    153                   }
   249    154                   _contextDataList.Clear();
   250    155                   _contextDataList = null;
   251    156   
   252    157                   _flags = SQLiteConnectionFlags.None;
   253         -                _invokeCallback = null;
   254         -                _stepCallback = null;
   255         -                _finalCallback = null;
   256         -                _compareCallback = null;
   257    158   
   258    159                   _InvokeFunc = null;
   259    160                   _StepFunc = null;
   260    161                   _FinalFunc = null;
   261    162                   _CompareFunc = null;
   262    163                   _base = null;
   263    164               }
................................................................................
   465    366             _base.ReturnBlob(context, (byte[])returnValue);
   466    367             return;
   467    368         }
   468    369       }
   469    370   
   470    371       /// <summary>
   471    372       /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method.
   472         -    /// Does nothing if there is no invoke callback configured.  WARNING: Must not throw exceptions.
          373  +    /// WARNING: Must not throw exceptions.
   473    374       /// </summary>
   474    375       /// <param name="context">A raw context pointer</param>
   475    376       /// <param name="nArgs">Number of arguments passed in</param>
   476    377       /// <param name="argsptr">A pointer to the array of arguments</param>
   477    378       internal void ScalarCallback(IntPtr context, int nArgs, IntPtr argsptr)
   478    379       {
   479         -        if (_invokeCallback != null)
          380  +        try
          381  +        {
          382  +            _context = context;
          383  +            SetReturnValue(context,
          384  +                Invoke(ConvertParams(nArgs, argsptr))); /* throw */
          385  +        }
          386  +#if !PLATFORM_COMPACTFRAMEWORK
          387  +        catch (Exception e) /* NOTE: Must catch ALL. */
   480    388           {
   481    389               try
   482    390               {
   483         -                _context = context;
   484         -                SetReturnValue(context,
   485         -                    _invokeCallback(ConvertParams(nArgs, argsptr))); /* throw */
   486         -            }
   487         -#if !PLATFORM_COMPACTFRAMEWORK
   488         -            catch (Exception e) /* NOTE: Must catch ALL. */
   489         -            {
   490         -                try
          391  +                if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
          392  +                        SQLiteConnectionFlags.LogCallbackException)
   491    393                   {
   492         -                    if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
   493         -                            SQLiteConnectionFlags.LogCallbackException)
   494         -                    {
   495         -                        SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format(
   496         -                            "Caught exception in {0} callback: {1}",
   497         -                            typeof(SQLiteFunctionInvokeCallback), e)); /* throw */
   498         -                    }
   499         -                }
   500         -                catch
   501         -                {
   502         -                    // do nothing.
          394  +                    SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format(
          395  +                        "Caught exception in \"Invoke\" method: {0}",
          396  +                        e)); /* throw */
   503    397                   }
   504    398               }
          399  +            catch
          400  +            {
          401  +                // do nothing.
          402  +            }
          403  +        }
   505    404   #else
   506         -            catch /* NOTE: Must catch ALL. */
   507         -            {
   508         -                // do nothing (Windows CE).
   509         -            }
          405  +        catch /* NOTE: Must catch ALL. */
          406  +        {
          407  +            // do nothing (Windows CE).
          408  +        }
   510    409   #endif
   511         -        }
   512    410       }
   513    411   
   514    412       /// <summary>
   515    413       /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function.
   516         -    /// Does nothing and returns zero if there is no compare callback configured.  WARNING: Must not throw exceptions.
          414  +    /// WARNING: Must not throw exceptions.
   517    415       /// </summary>
   518    416       /// <param name="ptr">Not used</param>
   519    417       /// <param name="len1">Length of the string pv1</param>
   520    418       /// <param name="ptr1">Pointer to the first string to compare</param>
   521    419       /// <param name="len2">Length of the string pv2</param>
   522    420       /// <param name="ptr2">Pointer to the second string to compare</param>
   523    421       /// <returns>Returns -1 if the first string is less than the second.  0 if they are equal, or 1 if the first string is greater
   524         -    /// than the second.  Returns 0 if there is no callback wrapper configured or an exception is caught.</returns>
          422  +    /// than the second.  Returns 0 if an exception is caught.</returns>
   525    423       internal int CompareCallback(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2)
   526    424       {
   527         -        if (_compareCallback != null)
          425  +        try
          426  +        {
          427  +            return Compare(SQLiteConvert.UTF8ToString(ptr1, len1),
          428  +                SQLiteConvert.UTF8ToString(ptr2, len2)); /* throw */
          429  +        }
          430  +#if !PLATFORM_COMPACTFRAMEWORK
          431  +        catch (Exception e) /* NOTE: Must catch ALL. */
   528    432           {
   529    433               try
   530    434               {
   531         -                return _compareCallback(SQLiteConvert.UTF8ToString(ptr1, len1),
   532         -                    SQLiteConvert.UTF8ToString(ptr2, len2)); /* throw */
   533         -            }
   534         -#if !PLATFORM_COMPACTFRAMEWORK
   535         -            catch (Exception e) /* NOTE: Must catch ALL. */
   536         -            {
   537         -                try
          435  +                if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
          436  +                        SQLiteConnectionFlags.LogCallbackException)
   538    437                   {
   539         -                    if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
   540         -                            SQLiteConnectionFlags.LogCallbackException)
   541         -                    {
   542         -                        SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format(
   543         -                            "Caught exception in {0} callback: {1}",
   544         -                            typeof(SQLiteCollationCompareCallback), e)); /* throw */
   545         -                    }
   546         -                }
   547         -                catch
   548         -                {
   549         -                    // do nothing.
          438  +                    SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format(
          439  +                        "Caught exception in \"Compare\" method: {0}",
          440  +                        e)); /* throw */
   550    441                   }
   551    442               }
          443  +            catch
          444  +            {
          445  +                // do nothing.
          446  +            }
          447  +        }
   552    448   #else
   553         -            catch /* NOTE: Must catch ALL. */
   554         -            {
   555         -                // do nothing (Windows CE).
   556         -            }
          449  +        catch /* NOTE: Must catch ALL. */
          450  +        {
          451  +            // do nothing (Windows CE).
          452  +        }
   557    453   #endif
   558         -        }
   559    454   
   560    455           return 0;
   561    456       }
   562    457   
   563    458       /// <summary>
   564    459       /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function.
   565         -    /// Does nothing and returns zero if there is no compare callback configured.  WARNING: Must not throw exceptions.
          460  +    /// WARNING: Must not throw exceptions.
   566    461       /// </summary>
   567    462       /// <param name="ptr">Not used</param>
   568    463       /// <param name="len1">Length of the string pv1</param>
   569    464       /// <param name="ptr1">Pointer to the first string to compare</param>
   570    465       /// <param name="len2">Length of the string pv2</param>
   571    466       /// <param name="ptr2">Pointer to the second string to compare</param>
   572    467       /// <returns>Returns -1 if the first string is less than the second.  0 if they are equal, or 1 if the first string is greater
   573         -    /// than the second.  Returns 0 if there is no callback wrapper configured or an exception is caught.</returns>
          468  +    /// than the second.  Returns 0 if an exception is caught.</returns>
   574    469       internal int CompareCallback16(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2)
   575    470       {
   576         -        if (_compareCallback != null)
          471  +        try
          472  +        {
          473  +            return Compare(SQLite3_UTF16.UTF16ToString(ptr1, len1),
          474  +                SQLite3_UTF16.UTF16ToString(ptr2, len2)); /* throw */
          475  +        }
          476  +#if !PLATFORM_COMPACTFRAMEWORK
          477  +        catch (Exception e) /* NOTE: Must catch ALL. */
   577    478           {
   578    479               try
   579    480               {
   580         -                return _compareCallback(SQLite3_UTF16.UTF16ToString(ptr1, len1),
   581         -                    SQLite3_UTF16.UTF16ToString(ptr2, len2)); /* throw */
   582         -            }
   583         -#if !PLATFORM_COMPACTFRAMEWORK
   584         -            catch (Exception e) /* NOTE: Must catch ALL. */
   585         -            {
   586         -                try
          481  +                if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
          482  +                        SQLiteConnectionFlags.LogCallbackException)
   587    483                   {
   588         -                    if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
   589         -                            SQLiteConnectionFlags.LogCallbackException)
   590         -                    {
   591         -                        SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format(
   592         -                            "Caught exception in {0} callback: {1}",
   593         -                            typeof(SQLiteCollationCompareCallback), e)); /* throw */
   594         -                    }
   595         -                }
   596         -                catch
   597         -                {
   598         -                    // do nothing.
          484  +                    SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format(
          485  +                        "Caught exception in \"Compare\" method: {0}",
          486  +                        e)); /* throw */
   599    487                   }
   600    488               }
          489  +            catch
          490  +            {
          491  +                // do nothing.
          492  +            }
          493  +        }
   601    494   #else
   602         -            catch /* NOTE: Must catch ALL. */
   603         -            {
   604         -                // do nothing (Windows CE).
   605         -            }
   606         -#endif
          495  +        catch /* NOTE: Must catch ALL. */
          496  +        {
          497  +            // do nothing (Windows CE).
   607    498           }
          499  +#endif
   608    500   
   609    501           return 0;
   610    502       }
   611    503   
   612    504       /// <summary>
   613    505       /// The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method.
   614         -    /// Does nothing if there is no step callback configured.  WARNING: Must not throw exceptions.
          506  +    /// WARNING: Must not throw exceptions.
   615    507       /// </summary>
   616    508       /// <remarks>
   617    509       /// This function takes care of doing the lookups and getting the important information put together to call the Step() function.
   618    510       /// That includes pulling out the user's contextData and updating it after the call is made.  We use a sorted list for this so
   619    511       /// binary searches can be done to find the data.
   620    512       /// </remarks>
   621    513       /// <param name="context">A raw context pointer</param>
   622    514       /// <param name="nArgs">Number of arguments passed in</param>
   623    515       /// <param name="argsptr">A pointer to the array of arguments</param>
   624    516       internal void StepCallback(IntPtr context, int nArgs, IntPtr argsptr)
   625    517       {
   626         -        if (_stepCallback != null)
          518  +        try
          519  +        {
          520  +            AggregateData data = null;
          521  +
          522  +            if (_base != null)
          523  +            {
          524  +                IntPtr nAux = _base.AggregateContext(context);
          525  +
          526  +                if ((_contextDataList != null) &&
          527  +                    !_contextDataList.TryGetValue(nAux, out data))
          528  +                {
          529  +                    data = new AggregateData();
          530  +                    _contextDataList[nAux] = data;
          531  +                }
          532  +            }
          533  +
          534  +            if (data == null)
          535  +                data = new AggregateData();
          536  +
          537  +            try
          538  +            {
          539  +                _context = context;
          540  +                Step(ConvertParams(nArgs, argsptr),
          541  +                    data._count, ref data._data); /* throw */
          542  +            }
          543  +            finally
          544  +            {
          545  +                data._count++;
          546  +            }
          547  +        }
          548  +#if !PLATFORM_COMPACTFRAMEWORK
          549  +        catch (Exception e) /* NOTE: Must catch ALL. */
   627    550           {
   628    551               try
   629    552               {
   630         -                AggregateData data = null;
   631         -
   632         -                if (_base != null)
          553  +                if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
          554  +                        SQLiteConnectionFlags.LogCallbackException)
   633    555                   {
   634         -                    IntPtr nAux = _base.AggregateContext(context);
   635         -
   636         -                    if ((_contextDataList != null) &&
   637         -                        !_contextDataList.TryGetValue(nAux, out data))
   638         -                    {
   639         -                        data = new AggregateData();
   640         -                        _contextDataList[nAux] = data;
   641         -                    }
   642         -                }
   643         -
   644         -                AggregateData newData = (data != null) ? data : new AggregateData();
   645         -
   646         -                try
   647         -                {
   648         -                    _context = context;
   649         -                    _stepCallback(ConvertParams(nArgs, argsptr),
   650         -                        newData._count, ref newData._data); /* throw */
   651         -                }
   652         -                finally
   653         -                {
   654         -                    newData._count++;
          556  +                    SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format(
          557  +                        "Caught exception in \"Step\" method: {1}",
          558  +                        e)); /* throw */
   655    559                   }
   656    560               }
   657         -#if !PLATFORM_COMPACTFRAMEWORK
   658         -            catch (Exception e) /* NOTE: Must catch ALL. */
          561  +            catch
   659    562               {
   660         -                try
   661         -                {
   662         -                    if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
   663         -                            SQLiteConnectionFlags.LogCallbackException)
   664         -                    {
   665         -                        SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format(
   666         -                            "Caught exception in {0} callback: {1}",
   667         -                            typeof(SQLiteFunctionStepCallback), e)); /* throw */
   668         -                    }
   669         -                }
   670         -                catch
   671         -                {
   672         -                    // do nothing.
   673         -                }
          563  +                // do nothing.
   674    564               }
          565  +        }
   675    566   #else
   676         -            catch /* NOTE: Must catch ALL. */
   677         -            {
   678         -                // do nothing (Windows CE).
   679         -            }
   680         -#endif
          567  +        catch /* NOTE: Must catch ALL. */
          568  +        {
          569  +            // do nothing (Windows CE).
   681    570           }
          571  +#endif
   682    572       }
   683    573   
   684    574       /// <summary>
   685    575       /// An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method.
   686         -    /// Does nothing if there is no final callback configured.  WARNING: Must not throw exceptions.
          576  +    /// WARNING: Must not throw exceptions.
   687    577       /// </summary>
   688    578       /// <param name="context">A raw context pointer</param>
   689    579       internal void FinalCallback(IntPtr context)
   690    580       {
   691         -        if (_finalCallback != null)
          581  +        try
          582  +        {
          583  +            object obj = null;
          584  +
          585  +            if (_base != null)
          586  +            {
          587  +                IntPtr n = _base.AggregateContext(context);
          588  +                AggregateData aggData;
          589  +
          590  +                if ((_contextDataList != null) &&
          591  +                    _contextDataList.TryGetValue(n, out aggData))
          592  +                {
          593  +                    obj = aggData._data;
          594  +                    _contextDataList.Remove(n);
          595  +                }
          596  +            }
          597  +
          598  +            try
          599  +            {
          600  +                _context = context;
          601  +                SetReturnValue(context, Final(obj)); /* throw */
          602  +            }
          603  +            finally
          604  +            {
          605  +                IDisposable disp = obj as IDisposable;
          606  +                if (disp != null) disp.Dispose(); /* throw */
          607  +            }
          608  +        }
          609  +#if !PLATFORM_COMPACTFRAMEWORK
          610  +        catch (Exception e) /* NOTE: Must catch ALL. */
   692    611           {
   693    612               try
   694    613               {
   695         -                object obj = null;
   696         -
   697         -                if (_base != null)
          614  +                if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
          615  +                        SQLiteConnectionFlags.LogCallbackException)
   698    616                   {
   699         -                    IntPtr n = _base.AggregateContext(context);
   700         -                    AggregateData aggData;
   701         -
   702         -                    if ((_contextDataList != null) &&
   703         -                        _contextDataList.TryGetValue(n, out aggData))
   704         -                    {
   705         -                        obj = aggData._data;
   706         -                        _contextDataList.Remove(n);
   707         -                    }
   708         -                }
   709         -
   710         -                try
   711         -                {
   712         -                    _context = context;
   713         -                    SetReturnValue(context, _finalCallback(obj)); /* throw */
   714         -                }
   715         -                finally
   716         -                {
   717         -                    IDisposable disp = obj as IDisposable;
   718         -                    if (disp != null) disp.Dispose(); /* throw */
          617  +                    SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format(
          618  +                        "Caught exception in \"Final\" method: {1}",
          619  +                        e)); /* throw */
   719    620                   }
   720    621               }
   721         -#if !PLATFORM_COMPACTFRAMEWORK
   722         -            catch (Exception e) /* NOTE: Must catch ALL. */
          622  +            catch
   723    623               {
   724         -                try
   725         -                {
   726         -                    if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
   727         -                            SQLiteConnectionFlags.LogCallbackException)
   728         -                    {
   729         -                        SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format(
   730         -                            "Caught exception in {0} callback: {1}",
   731         -                            typeof(SQLiteFunctionFinalCallback), e)); /* throw */
   732         -                    }
   733         -                }
   734         -                catch
   735         -                {
   736         -                    // do nothing.
   737         -                }
          624  +                // do nothing.
   738    625               }
          626  +        }
   739    627   #else
   740         -            catch /* NOTE: Must catch ALL. */
   741         -            {
   742         -                // do nothing (Windows CE).
   743         -            }
   744         -#endif
          628  +        catch /* NOTE: Must catch ALL. */
          629  +        {
          630  +            // do nothing (Windows CE).
   745    631           }
          632  +#endif
   746    633       }
   747    634   
   748    635       /// <summary>
   749    636       /// Using reflection, enumerate all assemblies in the current appdomain looking for classes that
   750    637       /// have a SQLiteFunctionAttribute attribute, and registering them accordingly.
   751    638       /// </summary>
   752    639   #if !PLATFORM_COMPACTFRAMEWORK
................................................................................
   858    745   
   859    746         foreach (SQLiteFunctionAttribute pr in _registeredFunctions)
   860    747         {
   861    748           f = (SQLiteFunction)Activator.CreateInstance(pr._instanceType);
   862    749   
   863    750           f._base = sqlbase;
   864    751           f._flags = flags;
   865         -        f._invokeCallback = f.Invoke;
   866         -        f._stepCallback = f.Step;
   867         -        f._finalCallback = f.Final;
   868         -        f._compareCallback = f.Compare;
   869    752           f._InvokeFunc = (pr.FuncType == FunctionType.Scalar) ? new SQLiteCallback(f.ScalarCallback) : null;
   870    753           f._StepFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.StepCallback) : null;
   871    754           f._FinalFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteFinalCallback(f.FinalCallback) : null;
   872    755           f._CompareFunc = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback) : null;
   873    756           f._CompareFunc16 = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback16) : null;
   874    757   
   875    758           if (pr.FuncType != FunctionType.Collation)