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

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

Overview
Comment:The SQLiteValue and SQLiteContext classes should implement the ISQLiteNativeHandle interface. Work in progress on documentation for the virtual tables support classes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | virtualTables
Files: files | file ages | folders
SHA1: c8d209d5f40dafbffd99d404e03fc4626e6d22da
User & Date: mistachkin 2013-06-24 22:49:45
Context
2013-06-24
22:50
Merge updates from trunk. check-in: d4f5e0a0ef user: mistachkin tags: virtualTables
22:49
The SQLiteValue and SQLiteContext classes should implement the ISQLiteNativeHandle interface. Work in progress on documentation for the virtual tables support classes. check-in: c8d209d5f4 user: mistachkin tags: virtualTables
2013-06-22
20:05
Also update error message wording. check-in: f01efa4daa user: mistachkin tags: virtualTables
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

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

    82     82       /// The modules created using this connection.
    83     83       /// </summary>
    84     84       protected Dictionary<string, SQLiteModule> _modules;
    85     85   #endif
    86     86   
    87     87       ///////////////////////////////////////////////////////////////////////////////////////////////
    88     88   
           89  +    /// <summary>
           90  +    /// Constructs the object used to interact with the SQLite core library
           91  +    /// using the UTF-8 text encoding.
           92  +    /// </summary>
           93  +    /// <param name="fmt">
           94  +    /// The DateTime format to be used when converting string values to a
           95  +    /// DateTime and binding DateTime parameters.
           96  +    /// </param>
           97  +    /// <param name="kind">
           98  +    /// The <see cref="DateTimeKind" /> to be used when creating DateTime
           99  +    /// values.
          100  +    /// </param>
          101  +    /// <param name="fmtString">
          102  +    /// The format string to be used when parsing and formatting DateTime
          103  +    /// values.
          104  +    /// </param>
          105  +    /// <param name="db">
          106  +    /// The native handle to be associated with the database connection.
          107  +    /// </param>
          108  +    /// <param name="fileName">
          109  +    /// The fully qualified file name associated with <paramref name="db "/>.
          110  +    /// </param>
          111  +    /// <param name="ownHandle">
          112  +    /// Non-zero if the newly created object instance will need to dispose
          113  +    /// of <paramref name="db" /> when it is no longer needed.
          114  +    /// </param>
    89    115       internal SQLite3(
    90    116           SQLiteDateFormats fmt,
    91    117           DateTimeKind kind,
    92    118           string fmtString,
    93    119           IntPtr db,
    94    120           string fileName,
    95    121           bool ownHandle
................................................................................
   131    157                   //}
   132    158   
   133    159                   //////////////////////////////////////
   134    160                   // release unmanaged resources here...
   135    161                   //////////////////////////////////////
   136    162   
   137    163   #if INTEROP_VIRTUAL_TABLE
          164  +                //
          165  +                // NOTE: If any modules were created, attempt to dispose of
          166  +                //       them now.  This code is designed to avoid throwing
          167  +                //       exceptions unless the Dispose method of the module
          168  +                //       itself throws an exception.
          169  +                //
   138    170                   if (_modules != null)
   139    171                   {
   140    172                       foreach (KeyValuePair<string, SQLiteModule> pair in _modules)
   141    173                       {
   142    174                           SQLiteModule module = pair.Value;
   143    175   
   144    176                           if (module == null)
................................................................................
   384    416       internal override bool IsOpen()
   385    417       {
   386    418           return (_sql != null) && !_sql.IsInvalid && !_sql.IsClosed;
   387    419       }
   388    420   
   389    421       internal override void Open(string strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool)
   390    422       {
          423  +      //
          424  +      // NOTE: If the database connection is currently open, attempt to
          425  +      //       close it now.  This must be done because the file name or
          426  +      //       other parameters that may impact the underlying database
          427  +      //       connection may have changed.
          428  +      //
   391    429         if (_sql != null) Close(true);
   392    430   
          431  +      //
          432  +      // NOTE: If the connection was not closed successfully, throw an
          433  +      //       exception now.
          434  +      //
   393    435         if (_sql != null)
   394    436             throw new SQLiteException("connection handle is still active");
   395    437   
   396    438         _usePool = usePool;
   397    439         _fileName = strFilename;
   398    440   
   399    441         if (usePool)

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

    17     17     using System.Runtime.InteropServices;
    18     18   
    19     19     /// <summary>
    20     20     /// Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode)
    21     21     /// </summary>
    22     22     internal sealed class SQLite3_UTF16 : SQLite3
    23     23     {
           24  +    /// <summary>
           25  +    /// Constructs the object used to interact with the SQLite core library
           26  +    /// using the UTF-8 text encoding.
           27  +    /// </summary>
           28  +    /// <param name="fmt">
           29  +    /// The DateTime format to be used when converting string values to a
           30  +    /// DateTime and binding DateTime parameters.
           31  +    /// </param>
           32  +    /// <param name="kind">
           33  +    /// The <see cref="DateTimeKind" /> to be used when creating DateTime
           34  +    /// values.
           35  +    /// </param>
           36  +    /// <param name="fmtString">
           37  +    /// The format string to be used when parsing and formatting DateTime
           38  +    /// values.
           39  +    /// </param>
           40  +    /// <param name="db">
           41  +    /// The native handle to be associated with the database connection.
           42  +    /// </param>
           43  +    /// <param name="fileName">
           44  +    /// The fully qualified file name associated with <paramref name="db "/>.
           45  +    /// </param>
           46  +    /// <param name="ownHandle">
           47  +    /// Non-zero if the newly created object instance will need to dispose
           48  +    /// of <paramref name="db" /> when it is no longer needed.
           49  +    /// </param>
    24     50       internal SQLite3_UTF16(
    25     51           SQLiteDateFormats fmt,
    26     52           DateTimeKind kind,
    27     53           string fmtString,
    28     54           IntPtr db,
    29     55           string fileName,
    30     56           bool ownHandle
................................................................................
    96    122           return Marshal.PtrToStringUni(b);
    97    123         else
    98    124           return Marshal.PtrToStringUni(b, nbytelen / 2);
    99    125       }
   100    126   
   101    127       internal override void Open(string strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool)
   102    128       {
          129  +      //
          130  +      // NOTE: If the database connection is currently open, attempt to
          131  +      //       close it now.  This must be done because the file name or
          132  +      //       other parameters that may impact the underlying database
          133  +      //       connection may have changed.
          134  +      //
   103    135         if (_sql != null) Close(true);
   104    136   
          137  +      //
          138  +      // NOTE: If the connection was not closed successfully, throw an
          139  +      //       exception now.
          140  +      //
   105    141         if (_sql != null)
   106    142             throw new SQLiteException("connection handle is still active");
   107    143   
   108    144         _usePool = usePool;
   109    145         _fileName = strFilename;
   110    146   
   111    147         if (usePool)

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

     9      9   using System.Globalization;
    10     10   using System.Runtime.InteropServices;
    11     11   using System.Text;
    12     12   
    13     13   namespace System.Data.SQLite
    14     14   {
    15     15       #region SQLiteContext Helper Class
    16         -    public sealed class SQLiteContext
           16  +    /// <summary>
           17  +    /// This class represents a context from the SQLite core library that can
           18  +    /// be passed to the sqlite3_result_*() and associated functions.
           19  +    /// </summary>
           20  +    public sealed class SQLiteContext : ISQLiteNativeHandle
    17     21       {
    18     22           #region Private Data
           23  +        /// <summary>
           24  +        /// The native context handle.
           25  +        /// </summary>
    19     26           private IntPtr pContext;
    20     27           #endregion
    21     28   
    22     29           ///////////////////////////////////////////////////////////////////////
    23     30   
    24     31           #region Private Constructors
           32  +        /// <summary>
           33  +        /// Constructs an instance of this class using the specified native
           34  +        /// context handle.
           35  +        /// </summary>
           36  +        /// <param name="pContext">
           37  +        /// The native context handle to use.
           38  +        /// </param>
    25     39           internal SQLiteContext(IntPtr pContext)
    26     40           {
    27     41               this.pContext = pContext;
    28     42           }
    29     43           #endregion
    30     44   
    31     45           ///////////////////////////////////////////////////////////////////////
    32     46   
           47  +        #region ISQLiteNativeHandle Members
           48  +        /// <summary>
           49  +        /// Returns the underlying SQLite native handle associated with this
           50  +        /// object instance.
           51  +        /// </summary>
           52  +        public virtual IntPtr NativeHandle
           53  +        {
           54  +            get { return pContext; }
           55  +        }
           56  +        #endregion
           57  +
           58  +        ///////////////////////////////////////////////////////////////////////
           59  +
    33     60           #region Public Methods
           61  +        /// <summary>
           62  +        /// Sets the context result to NULL.
           63  +        /// </summary>
    34     64           public void SetNull()
    35     65           {
    36     66               if (pContext == IntPtr.Zero)
    37     67                   throw new InvalidOperationException();
    38     68   
    39     69               UnsafeNativeMethods.sqlite3_result_null(pContext);
    40     70           }
    41     71   
    42     72           ///////////////////////////////////////////////////////////////////////
    43     73   
           74  +        /// <summary>
           75  +        /// Sets the context result to the specified <see cref="System.Double" />
           76  +        /// value.
           77  +        /// </summary>
           78  +        /// <param name="value">
           79  +        /// The <see cref="System.Double" /> value to use.
           80  +        /// </param>
    44     81           public void SetDouble(double value)
    45     82           {
    46     83               if (pContext == IntPtr.Zero)
    47     84                   throw new InvalidOperationException();
    48     85   
    49     86   #if !PLATFORM_COMPACTFRAMEWORK
    50     87               UnsafeNativeMethods.sqlite3_result_double(pContext, value);
................................................................................
    53     90   #else
    54     91               throw new NotImplementedException();
    55     92   #endif
    56     93           }
    57     94   
    58     95           ///////////////////////////////////////////////////////////////////////
    59     96   
           97  +        /// <summary>
           98  +        /// Sets the context result to the specified <see cref="System.Int32" />
           99  +        /// value.
          100  +        /// </summary>
          101  +        /// <param name="value">
          102  +        /// The <see cref="System.Int32" /> value to use.
          103  +        /// </param>
    60    104           public void SetInt(int value)
    61    105           {
    62    106               if (pContext == IntPtr.Zero)
    63    107                   throw new InvalidOperationException();
    64    108   
    65    109               UnsafeNativeMethods.sqlite3_result_int(pContext, value);
    66    110           }
    67    111   
    68    112           ///////////////////////////////////////////////////////////////////////
    69    113   
          114  +        /// <summary>
          115  +        /// Sets the context result to the specified <see cref="System.Int64" />
          116  +        /// value.
          117  +        /// </summary>
          118  +        /// <param name="value">
          119  +        /// The <see cref="System.Int64" /> value to use.
          120  +        /// </param>
    70    121           public void SetInt64(long value)
    71    122           {
    72    123               if (pContext == IntPtr.Zero)
    73    124                   throw new InvalidOperationException();
    74    125   
    75    126   #if !PLATFORM_COMPACTFRAMEWORK
    76    127               UnsafeNativeMethods.sqlite3_result_int64(pContext, value);
................................................................................
    79    130   #else
    80    131               throw new NotImplementedException();
    81    132   #endif
    82    133           }
    83    134   
    84    135           ///////////////////////////////////////////////////////////////////////
    85    136   
          137  +        /// <summary>
          138  +        /// Sets the context result to the specified <see cref="System.String" />
          139  +        /// value.
          140  +        /// </summary>
          141  +        /// <param name="value">
          142  +        /// The <see cref="System.String" /> value to use.  This value will be
          143  +        /// converted to the UTF-8 encoding prior to being used.
          144  +        /// </param>
    86    145           public void SetString(string value)
    87    146           {
    88    147               if (pContext == IntPtr.Zero)
    89    148                   throw new InvalidOperationException();
    90    149   
    91    150               byte[] bytes = SQLiteString.GetUtf8BytesFromString(value);
    92    151   
................................................................................
    95    154   
    96    155               UnsafeNativeMethods.sqlite3_result_text(
    97    156                   pContext, bytes, bytes.Length, (IntPtr)(-1));
    98    157           }
    99    158   
   100    159           ///////////////////////////////////////////////////////////////////////
   101    160   
          161  +        /// <summary>
          162  +        /// Sets the context result to the specified <see cref="System.String" />
          163  +        /// value containing an error message.
          164  +        /// </summary>
          165  +        /// <param name="value">
          166  +        /// The <see cref="System.String" /> value containing the error message
          167  +        /// text.  This value will be converted to the UTF-8 encoding prior to
          168  +        /// being used.
          169  +        /// </param>
   102    170           public void SetError(string value)
   103    171           {
   104    172               if (pContext == IntPtr.Zero)
   105    173                   throw new InvalidOperationException();
   106    174   
   107    175               byte[] bytes = SQLiteString.GetUtf8BytesFromString(value);
   108    176   
................................................................................
   111    179   
   112    180               UnsafeNativeMethods.sqlite3_result_error(
   113    181                   pContext, bytes, bytes.Length);
   114    182           }
   115    183   
   116    184           ///////////////////////////////////////////////////////////////////////
   117    185   
          186  +        /// <summary>
          187  +        /// Sets the context result to the specified <see cref="SQLiteErrorCode" />
          188  +        /// value.
          189  +        /// </summary>
          190  +        /// <param name="value">
          191  +        /// The <see cref="SQLiteErrorCode" /> value to use.
          192  +        /// </param>
   118    193           public void SetErrorCode(SQLiteErrorCode value)
   119    194           {
   120    195               if (pContext == IntPtr.Zero)
   121    196                   throw new InvalidOperationException();
   122    197   
   123    198               UnsafeNativeMethods.sqlite3_result_error_code(pContext, value);
   124    199           }
   125    200   
   126    201           ///////////////////////////////////////////////////////////////////////
   127    202   
          203  +        /// <summary>
          204  +        /// Sets the context result to contain the error code SQLITE_TOOBIG.
          205  +        /// </summary>
   128    206           public void SetErrorTooBig()
   129    207           {
   130    208               if (pContext == IntPtr.Zero)
   131    209                   throw new InvalidOperationException();
   132    210   
   133    211               UnsafeNativeMethods.sqlite3_result_error_toobig(pContext);
   134    212           }
   135    213   
   136    214           ///////////////////////////////////////////////////////////////////////
   137    215   
          216  +        /// <summary>
          217  +        /// Sets the context result to contain the error code SQLITE_NOMEM.
          218  +        /// </summary>
   138    219           public void SetErrorNoMemory()
   139    220           {
   140    221               if (pContext == IntPtr.Zero)
   141    222                   throw new InvalidOperationException();
   142    223   
   143    224               UnsafeNativeMethods.sqlite3_result_error_nomem(pContext);
   144    225           }
   145    226   
   146    227           ///////////////////////////////////////////////////////////////////////
   147    228   
          229  +        /// <summary>
          230  +        /// Sets the context result to the specified <see cref="System.Byte[]" />
          231  +        /// value.
          232  +        /// </summary>
          233  +        /// <param name="value">
          234  +        /// The <see cref="System.Byte[]" /> value to use.
          235  +        /// </param>
   148    236           public void SetBlob(byte[] value)
   149    237           {
   150    238               if (pContext == IntPtr.Zero)
   151    239                   throw new InvalidOperationException();
   152    240   
   153    241               if (value == null)
   154    242                   throw new ArgumentNullException("value");
................................................................................
   155    243   
   156    244               UnsafeNativeMethods.sqlite3_result_blob(
   157    245                   pContext, value, value.Length, (IntPtr)(-1));
   158    246           }
   159    247   
   160    248           ///////////////////////////////////////////////////////////////////////
   161    249   
          250  +        /// <summary>
          251  +        /// Sets the context result to a BLOB of zeros of the specified size.
          252  +        /// </summary>
          253  +        /// <param name="value">
          254  +        /// The number of zero bytes to use for the BLOB context result.
          255  +        /// </param>
   162    256           public void SetZeroBlob(int value)
   163    257           {
   164    258               if (pContext == IntPtr.Zero)
   165    259                   throw new InvalidOperationException();
   166    260   
   167    261               UnsafeNativeMethods.sqlite3_result_zeroblob(pContext, value);
   168    262           }
   169    263   
   170    264           ///////////////////////////////////////////////////////////////////////
   171    265   
   172         -        public void SetValue(IntPtr pValue)
          266  +        /// <summary>
          267  +        /// Sets the context result to the specified <see cref="SQLiteValue" />.
          268  +        /// </summary>
          269  +        /// <param name="value">
          270  +        /// The <see cref="SQLiteValue" /> to use.
          271  +        /// </param>
          272  +        public void SetValue(SQLiteValue value)
   173    273           {
   174    274               if (pContext == IntPtr.Zero)
   175    275                   throw new InvalidOperationException();
   176    276   
   177         -            UnsafeNativeMethods.sqlite3_result_value(pContext, pValue);
          277  +            if (value == null)
          278  +                throw new ArgumentNullException("value");
          279  +
          280  +            UnsafeNativeMethods.sqlite3_result_value(
          281  +                pContext, value.NativeHandle);
   178    282           }
   179    283           #endregion
   180    284       }
   181    285       #endregion
   182    286   
   183    287       ///////////////////////////////////////////////////////////////////////////
   184    288   
   185    289       #region SQLiteValue Helper Class
   186         -    public sealed class SQLiteValue
          290  +    public sealed class SQLiteValue : ISQLiteNativeHandle
   187    291       {
   188    292           #region Private Data
          293  +        /// <summary>
          294  +        /// The native value handle.
          295  +        /// </summary>
   189    296           private IntPtr pValue;
   190    297           #endregion
   191    298   
   192    299           ///////////////////////////////////////////////////////////////////////
   193    300   
   194    301           #region Private Constructors
          302  +        /// <summary>
          303  +        /// Constructs an instance of this class using the specified native
          304  +        /// value handle.
          305  +        /// </summary>
          306  +        /// <param name="pContext">
          307  +        /// The native value handle to use.
          308  +        /// </param>
   195    309           internal SQLiteValue(IntPtr pValue)
   196    310           {
   197    311               this.pValue = pValue;
   198    312           }
   199    313           #endregion
   200    314   
   201    315           ///////////////////////////////////////////////////////////////////////
   202    316   
   203    317           #region Private Methods
          318  +        /// <summary>
          319  +        /// Invalidates the native value handle, thereby preventing further
          320  +        /// access to it from this object instance.
          321  +        /// </summary>
   204    322           private void PreventNativeAccess()
   205    323           {
   206    324               pValue = IntPtr.Zero;
   207    325           }
   208    326           #endregion
   209    327   
   210    328           ///////////////////////////////////////////////////////////////////////
   211    329   
          330  +        #region ISQLiteNativeHandle Members
          331  +        /// <summary>
          332  +        /// Returns the underlying SQLite native handle associated with this
          333  +        /// object instance.
          334  +        /// </summary>
          335  +        public virtual IntPtr NativeHandle
          336  +        {
          337  +            get { return pValue; }
          338  +        }
          339  +        #endregion
          340  +
          341  +        ///////////////////////////////////////////////////////////////////////
          342  +
   212    343           #region Public Properties
   213    344           private bool persisted;
          345  +        /// <summary>
          346  +        /// Returns non-zero if the native SQLite value has been successfully
          347  +        /// persisted as a managed value within this object instance (i.e. the
          348  +        /// <see cref="Value" /> property may then be read successfully).
          349  +        /// </summary>
   214    350           public bool Persisted
   215    351           {
   216    352               get { return persisted; }
   217    353           }
   218    354   
   219    355           ///////////////////////////////////////////////////////////////////////
   220    356   
   221    357           private object value;
          358  +        /// <summary>
          359  +        /// If the managed value for this object instance is available (i.e. it
          360  +        /// has been previously persisted via the <see cref="Persist"/>) method,
          361  +        /// that value is returned; otherwise, an exception is thrown.  The
          362  +        /// returned value may be null.
          363  +        /// </summary>
   222    364           public object Value
   223    365           {
   224    366               get
   225    367               {
   226    368                   if (!persisted)
   227    369                   {
   228    370                       throw new InvalidOperationException(
................................................................................
   233    375               }
   234    376           }
   235    377           #endregion
   236    378   
   237    379           ///////////////////////////////////////////////////////////////////////
   238    380   
   239    381           #region Public Methods
          382  +        /// <summary>
          383  +        /// Gets and returns the type affinity associated with this value.
          384  +        /// </summary>
          385  +        /// <returns>
          386  +        /// The type affinity associated with this value.
          387  +        /// </returns>
   240    388           public TypeAffinity GetTypeAffinity()
   241    389           {
   242    390               if (pValue == IntPtr.Zero) return TypeAffinity.None;
   243    391               return UnsafeNativeMethods.sqlite3_value_type(pValue);
   244    392           }
   245    393   
   246    394           ///////////////////////////////////////////////////////////////////////
   247    395   
          396  +        /// <summary>
          397  +        /// Gets and returns the number of bytes associated with this value, if
          398  +        /// it refers to a UTF-8 encoded string.
          399  +        /// </summary>
          400  +        /// <returns>
          401  +        /// The number of bytes associated with this value.  The returned value
          402  +        /// may be zero.
          403  +        /// </returns>
   248    404           public int GetBytes()
   249    405           {
   250    406               if (pValue == IntPtr.Zero) return 0;
   251    407               return UnsafeNativeMethods.sqlite3_value_bytes(pValue);
   252    408           }
   253    409   
   254    410           ///////////////////////////////////////////////////////////////////////
   255    411   
          412  +        /// <summary>
          413  +        /// Gets and returns the <see cref="System.Int32" /> associated with
          414  +        /// this value.
          415  +        /// </summary>
          416  +        /// <returns>
          417  +        /// The <see cref="System.Int32" /> associated with this value.
          418  +        /// </returns>
   256    419           public int GetInt()
   257    420           {
   258    421               if (pValue == IntPtr.Zero) return default(int);
   259    422               return UnsafeNativeMethods.sqlite3_value_int(pValue);
   260    423           }
   261    424   
   262    425           ///////////////////////////////////////////////////////////////////////
   263    426   
          427  +        /// <summary>
          428  +        /// Gets and returns the <see cref="System.Int64" /> associated with
          429  +        /// this value.
          430  +        /// </summary>
          431  +        /// <returns>
          432  +        /// The <see cref="System.Int64" /> associated with this value.
          433  +        /// </returns>
   264    434           public long GetInt64()
   265    435           {
   266    436               if (pValue == IntPtr.Zero) return default(long);
   267    437   
   268    438   #if !PLATFORM_COMPACTFRAMEWORK
   269    439               return UnsafeNativeMethods.sqlite3_value_int64(pValue);
   270    440   #elif !SQLITE_STANDARD
................................................................................
   274    444   #else
   275    445               throw new NotImplementedException();
   276    446   #endif
   277    447           }
   278    448   
   279    449           ///////////////////////////////////////////////////////////////////////
   280    450   
          451  +        /// <summary>
          452  +        /// Gets and returns the <see cref="System.Double" /> associated with
          453  +        /// this value.
          454  +        /// </summary>
          455  +        /// <returns>
          456  +        /// The <see cref="System.Double" /> associated with this value.
          457  +        /// </returns>
   281    458           public double GetDouble()
   282    459           {
   283    460               if (pValue == IntPtr.Zero) return default(double);
   284    461   
   285    462   #if !PLATFORM_COMPACTFRAMEWORK
   286    463               return UnsafeNativeMethods.sqlite3_value_double(pValue);
   287    464   #elif !SQLITE_STANDARD
................................................................................
   291    468   #else
   292    469               throw new NotImplementedException();
   293    470   #endif
   294    471           }
   295    472   
   296    473           ///////////////////////////////////////////////////////////////////////
   297    474   
          475  +        /// <summary>
          476  +        /// Gets and returns the <see cref="System.String" /> associated with
          477  +        /// this value.
          478  +        /// </summary>
          479  +        /// <returns>
          480  +        /// The <see cref="System.String" /> associated with this value.  The
          481  +        /// value is converted from the UTF-8 encoding prior to being returned.
          482  +        /// </returns>
   298    483           public string GetString()
   299    484           {
   300    485               if (pValue == IntPtr.Zero) return null;
   301    486               return SQLiteString.StringFromUtf8IntPtr(pValue, GetBytes());
   302    487           }
   303    488   
   304    489           ///////////////////////////////////////////////////////////////////////
   305    490   
          491  +        /// <summary>
          492  +        /// Gets and returns the <see cref="System.Byte[]" /> associated with
          493  +        /// this value.
          494  +        /// </summary>
          495  +        /// <returns>
          496  +        /// The <see cref="System.Byte[]" /> associated with this value.
          497  +        /// </returns>
   306    498           public byte[] GetBlob()
   307    499           {
   308    500               if (pValue == IntPtr.Zero) return null;
   309    501               return SQLiteMarshal.BytesFromIntPtr(pValue, GetBytes());
   310    502           }
   311    503   
   312    504           ///////////////////////////////////////////////////////////////////////
   313    505   
          506  +        /// <summary>
          507  +        /// Uses the native value handle to obtain and store the managed value
          508  +        /// for this object instance, thus saving it for later use.  The type
          509  +        /// of the managed value is determined by the type affinity of the
          510  +        /// native value.  If the type affinity is not recognized by this
          511  +        /// method, no work is done and false is returned.
          512  +        /// </summary>
          513  +        /// <returns>
          514  +        /// Non-zero if the native value was persisted successfully.
          515  +        /// </returns>
   314    516           public bool Persist()
   315    517           {
   316    518               switch (GetTypeAffinity())
   317    519               {
   318    520                   case TypeAffinity.Uninitialized:
   319    521                       {
   320    522                           value = null;
................................................................................
   360    562           #endregion
   361    563       }
   362    564       #endregion
   363    565   
   364    566       ///////////////////////////////////////////////////////////////////////////
   365    567   
   366    568       #region SQLiteIndexConstraintOp Enumeration
   367         -    /* [Flags()] */
          569  +    /// <summary>
          570  +    /// These are the allowed values for the operators that are part of a
          571  +    /// constraint term in the WHERE clause of a query that uses a virtual
          572  +    /// table.
          573  +    /// </summary>
   368    574       public enum SQLiteIndexConstraintOp : byte
   369    575       {
          576  +        /// <summary>
          577  +        /// This value represents the equality operator.
          578  +        /// </summary>
   370    579           EqualTo = 2,
          580  +
          581  +        /// <summary>
          582  +        /// This value represents the greater than operator.
          583  +        /// </summary>
   371    584           GreaterThan = 4,
          585  +
          586  +        /// <summary>
          587  +        /// This value represents the less than or equal to operator.
          588  +        /// </summary>
   372    589           LessThanOrEqualTo = 8,
          590  +
          591  +        /// <summary>
          592  +        /// This value represents the less than operator.
          593  +        /// </summary>
   373    594           LessThan = 16,
          595  +
          596  +        /// <summary>
          597  +        /// This value represents the greater than or equal to operator.
          598  +        /// </summary>
   374    599           GreaterThanOrEqualTo = 32,
          600  +
          601  +        /// <summary>
          602  +        /// This value represents the MATCH operator.
          603  +        /// </summary>
   375    604           Match = 64
   376    605       }
   377    606       #endregion
   378    607   
   379    608       ///////////////////////////////////////////////////////////////////////////
   380    609   
   381    610       #region SQLiteIndexConstraint Helper Class
          611  +    /// <summary>
          612  +    /// This class represents the native sqlite3_index_constraint structure
          613  +    /// from the SQLite core library.
          614  +    /// </summary>
   382    615       public sealed class SQLiteIndexConstraint
   383    616       {
   384    617           #region Internal Constructors
          618  +        /// <summary>
          619  +        /// Constructs an instance of this class using the specified native
          620  +        /// sqlite3_index_constraint structure.
          621  +        /// </summary>
          622  +        /// <param name="constraint">
          623  +        /// The native sqlite3_index_constraint structure to use.
          624  +        /// </param>
   385    625           internal SQLiteIndexConstraint(
   386    626               UnsafeNativeMethods.sqlite3_index_constraint constraint
   387    627               )
   388    628               : this(constraint.iColumn, constraint.op, constraint.usable,
   389    629                      constraint.iTermOffset)
   390    630           {
   391    631               // do nothing.
   392    632           }
   393    633           #endregion
   394    634   
   395    635           //////////////////////////////////////////////////////////////////////
   396    636   
   397    637           #region Private Constructors
          638  +        /// <summary>
          639  +        /// Constructs an instance of this class using the specified field
          640  +        /// values.
          641  +        /// </summary>
          642  +        /// <param name="iColumn">
          643  +        /// Column on left-hand side of constraint.
          644  +        /// </param>
          645  +        /// <param name="op">
          646  +        /// Constraint operator (<see cref="SQLiteIndexConstraintOp" />).
          647  +        /// </param>
          648  +        /// <param name="usable">
          649  +        /// True if this constraint is usable.
          650  +        /// </param>
          651  +        /// <param name="iTermOffset">
          652  +        /// Used internally - <see cref="ISQLiteManagedModule.BestIndex" />
          653  +        /// should ignore.
          654  +        /// </param>
   398    655           private SQLiteIndexConstraint(
   399    656               int iColumn,
   400    657               SQLiteIndexConstraintOp op,
   401    658               byte usable,
   402    659               int iTermOffset
   403    660               )
   404    661           {
................................................................................
   408    665               this.iTermOffset = iTermOffset;
   409    666           }
   410    667           #endregion
   411    668   
   412    669           //////////////////////////////////////////////////////////////////////
   413    670   
   414    671           #region Public Fields
          672  +        /// <summary>
          673  +        /// Column on left-hand side of constraint.
          674  +        /// </summary>
   415    675           public int iColumn;
   416    676   
   417    677           //////////////////////////////////////////////////////////////////////
   418    678   
          679  +        /// <summary>
          680  +        /// Constraint operator (<see cref="SQLiteIndexConstraintOp" />).
          681  +        /// </summary>
   419    682           public SQLiteIndexConstraintOp op;
   420    683   
   421    684           //////////////////////////////////////////////////////////////////////
   422    685   
          686  +        /// <summary>
          687  +        /// True if this constraint is usable.
          688  +        /// </summary>
   423    689           public byte usable;
   424    690   
   425    691           //////////////////////////////////////////////////////////////////////
   426    692   
          693  +        /// <summary>
          694  +        /// Used internally - <see cref="ISQLiteManagedModule.BestIndex" />
          695  +        /// should ignore.
          696  +        /// </summary>
   427    697           public int iTermOffset;
   428    698           #endregion
   429    699       }
   430    700       #endregion
   431    701   
   432    702       ///////////////////////////////////////////////////////////////////////////
   433    703   
   434    704       #region SQLiteIndexOrderBy Helper Class
          705  +    /// <summary>
          706  +    /// This class represents the native sqlite3_index_orderby structure from
          707  +    /// the SQLite core library.
          708  +    /// </summary>
   435    709       public sealed class SQLiteIndexOrderBy
   436    710       {
   437    711           #region Internal Constructors
          712  +        /// <summary>
          713  +        /// Constructs an instance of this class using the specified native
          714  +        /// sqlite3_index_orderby structure.
          715  +        /// </summary>
          716  +        /// <param name="orderBy">
          717  +        /// The native sqlite3_index_orderby structure to use.
          718  +        /// </param>
   438    719           internal SQLiteIndexOrderBy(
   439    720               UnsafeNativeMethods.sqlite3_index_orderby orderBy
   440    721               )
   441    722               : this(orderBy.iColumn, orderBy.desc)
   442    723           {
   443    724               // do nothing.
   444    725           }
   445    726           #endregion
   446    727   
   447    728           //////////////////////////////////////////////////////////////////////
   448    729   
   449    730           #region Private Constructors
          731  +        /// <summary>
          732  +        /// Constructs an instance of this class using the specified field
          733  +        /// values.
          734  +        /// </summary>
          735  +        /// <param name="iColumn">
          736  +        /// Column number.
          737  +        /// </param>
          738  +        /// <param name="desc">
          739  +        /// True for DESC.  False for ASC.
          740  +        /// </param>
   450    741           private SQLiteIndexOrderBy(
   451    742               int iColumn,
   452    743               byte desc
   453    744               )
   454    745           {
   455    746               this.iColumn = iColumn;
   456    747               this.desc = desc;
   457    748           }
   458    749           #endregion
   459    750   
   460    751           //////////////////////////////////////////////////////////////////////
   461    752   
   462    753           #region Public Fields
   463         -        public int iColumn; /* Column number */
          754  +        /// <summary>
          755  +        /// Column number.
          756  +        /// </summary>
          757  +        public int iColumn;
   464    758   
   465    759           //////////////////////////////////////////////////////////////////////
   466    760   
   467         -        public byte desc;   /* True for DESC.  False for ASC. */
          761  +        /// <summary>
          762  +        /// True for DESC.  False for ASC.
          763  +        /// </summary>
          764  +        public byte desc;
   468    765           #endregion
   469    766       }
   470    767       #endregion
   471    768   
   472    769       ///////////////////////////////////////////////////////////////////////////
   473    770   
   474    771       #region SQLiteIndexConstraintUsage Helper Class
          772  +    /// <summary>
          773  +    /// This class represents the native sqlite3_index_constraint_usage
          774  +    /// structure from the SQLite core library.
          775  +    /// </summary>
   475    776       public sealed class SQLiteIndexConstraintUsage
   476    777       {
   477    778           #region Internal Constructors
          779  +        /// <summary>
          780  +        /// Constructs an instance of this class using the specified native
          781  +        /// sqlite3_index_constraint_usage structure.
          782  +        /// </summary>
          783  +        /// <param name="constraintUsage">
          784  +        /// The native sqlite3_index_constraint_usage structure to use.
          785  +        /// </param>
   478    786           internal SQLiteIndexConstraintUsage(
   479    787               UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage
   480    788               )
   481    789               : this(constraintUsage.argvIndex, constraintUsage.omit)
   482    790           {
   483    791               // do nothing.
   484    792           }
   485    793           #endregion
   486    794   
   487    795           //////////////////////////////////////////////////////////////////////
   488    796   
   489    797           #region Private Constructors
          798  +        /// <summary>
          799  +        /// Constructs an instance of this class using the specified field
          800  +        /// values.
          801  +        /// </summary>
          802  +        /// <param name="argvIndex">
          803  +        /// If greater than 0, constraint is part of argv to xFilter.
          804  +        /// </param>
          805  +        /// <param name="omit">
          806  +        /// Do not code a test for this constraint.
          807  +        /// </param>
   490    808           private SQLiteIndexConstraintUsage(
   491    809               int argvIndex,
   492    810               byte omit
   493    811               )
   494    812           {
   495    813               this.argvIndex = argvIndex;
   496    814               this.omit = omit;
   497    815           }
   498    816           #endregion
   499    817   
   500    818           ///////////////////////////////////////////////////////////////////////
   501    819   
   502    820           #region Public Fields
          821  +        /// <summary>
          822  +        /// If greater than 0, constraint is part of argv to xFilter.
          823  +        /// </summary>
   503    824           public int argvIndex;
   504    825   
   505    826           ///////////////////////////////////////////////////////////////////////
   506    827   
          828  +        /// <summary>
          829  +        /// Do not code a test for this constraint.
          830  +        /// </summary>
   507    831           public byte omit;
   508    832           #endregion
   509    833       }
   510    834       #endregion
   511    835   
   512    836       ///////////////////////////////////////////////////////////////////////////
   513    837   
   514    838       #region SQLiteIndexInputs Helper Class
          839  +    /// <summary>
          840  +    /// This class represents the various inputs provided by the SQLite core
          841  +    /// library to the <see cref="ISQLiteManagedModule.BestIndex" /> method.
          842  +    /// </summary>
   515    843       public sealed class SQLiteIndexInputs
   516    844       {
   517    845           #region Internal Constructors
          846  +        /// <summary>
          847  +        /// Constructs an instance of this class.
          848  +        /// </summary>
          849  +        /// <param name="nConstraint">
          850  +        /// The number of <see cref="SQLiteIndexConstraint" /> instances to
          851  +        /// pre-allocate space for.
          852  +        /// </param>
          853  +        /// <param name="nOrderBy">
          854  +        /// The number of <see cref="SQLiteIndexOrderBy" /> instances to
          855  +        /// pre-allocate space for.
          856  +        /// </param>
   518    857           internal SQLiteIndexInputs(int nConstraint, int nOrderBy)
   519    858           {
   520    859               constraints = new SQLiteIndexConstraint[nConstraint];
   521    860               orderBys = new SQLiteIndexOrderBy[nOrderBy];
   522    861           }
   523    862           #endregion
   524    863   
   525    864           ///////////////////////////////////////////////////////////////////////
   526    865   
   527    866           #region Public Properties
   528    867           private SQLiteIndexConstraint[] constraints;
          868  +        /// <summary>
          869  +        /// An array of <see cref="SQLiteIndexConstraint" /> object instances,
          870  +        /// each containing information supplied by the SQLite core library.
          871  +        /// </summary>
   529    872           public SQLiteIndexConstraint[] Constraints
   530    873           {
   531    874               get { return constraints; }
   532    875           }
   533    876   
   534    877           ///////////////////////////////////////////////////////////////////////
   535    878   
   536    879           private SQLiteIndexOrderBy[] orderBys;
          880  +        /// <summary>
          881  +        /// An array of <see cref="SQLiteIndexOrderBy" /> object instances,
          882  +        /// each containing information supplied by the SQLite core library.
          883  +        /// </summary>
   537    884           public SQLiteIndexOrderBy[] OrderBys
   538    885           {
   539    886               get { return orderBys; }
   540    887           }
   541    888           #endregion
   542    889       }
   543    890       #endregion
   544    891   
   545    892       ///////////////////////////////////////////////////////////////////////////
   546    893   
   547    894       #region SQLiteIndexOutputs Helper Class
          895  +    /// <summary>
          896  +    /// This class represents the various outputs provided to the SQLite core
          897  +    /// library by the <see cref="ISQLiteManagedModule.BestIndex" /> method.
          898  +    /// </summary>
   548    899       public sealed class SQLiteIndexOutputs
   549    900       {
   550    901           #region Internal Constructors
          902  +        /// <summary>
          903  +        /// Constructs an instance of this class.
          904  +        /// </summary>
          905  +        /// <param name="nConstraint">
          906  +        /// The number of <see cref="SQLiteIndexConstraintUsage" /> instances
          907  +        /// to pre-allocate space for.
          908  +        /// </param>
   551    909           internal SQLiteIndexOutputs(int nConstraint)
   552    910           {
   553    911               constraintUsages = new SQLiteIndexConstraintUsage[nConstraint];
   554    912           }
   555    913           #endregion
   556    914   
   557    915           ///////////////////////////////////////////////////////////////////////
   558    916   
   559    917           #region Public Properties
   560    918           private SQLiteIndexConstraintUsage[] constraintUsages;
          919  +        /// <summary>
          920  +        /// An array of <see cref="SQLiteIndexConstraintUsage" /> object
          921  +        /// instances, each containing information to be supplied to the SQLite
          922  +        /// core library.
          923  +        /// </summary>
   561    924           public SQLiteIndexConstraintUsage[] ConstraintUsages
   562    925           {
   563    926               get { return constraintUsages; }
   564    927           }
   565    928   
   566    929           ///////////////////////////////////////////////////////////////////////
   567    930   
   568    931           private int indexNumber;
          932  +        /// <summary>
          933  +        /// Number used to help identify the selected index.  This value will
          934  +        /// later be provided to the <see cref="ISQLiteManagedModule.Filter" />
          935  +        /// method.
          936  +        /// </summary>
   569    937           public int IndexNumber
   570    938           {
   571    939               get { return indexNumber; }
   572    940               set { indexNumber = value; }
   573    941           }
   574    942   
   575    943           ///////////////////////////////////////////////////////////////////////
   576    944   
   577    945           private string indexString;
          946  +        /// <summary>
          947  +        /// String used to help identify the selected index.  This value will
          948  +        /// later be provided to the <see cref="ISQLiteManagedModule.Filter" />
          949  +        /// method.
          950  +        /// </summary>
   578    951           public string IndexString
   579    952           {
   580    953               get { return indexString; }
   581    954               set { indexString = value; }
   582    955           }
   583    956   
   584    957           ///////////////////////////////////////////////////////////////////////
   585    958   
   586    959           private int needToFreeIndexString;
          960  +        /// <summary>
          961  +        /// Non-zero if the index string must be freed by the SQLite core
          962  +        /// library.
          963  +        /// </summary>
   587    964           public int NeedToFreeIndexString
   588    965           {
   589    966               get { return needToFreeIndexString; }
   590    967               set { needToFreeIndexString = value; }
   591    968           }
   592    969   
   593    970           ///////////////////////////////////////////////////////////////////////
   594    971   
   595    972           private int orderByConsumed;
          973  +        /// <summary>
          974  +        /// True if output is already ordered.
          975  +        /// </summary>
   596    976           public int OrderByConsumed
   597    977           {
   598    978               get { return orderByConsumed; }
   599    979               set { orderByConsumed = value; }
   600    980           }
   601    981   
   602    982           ///////////////////////////////////////////////////////////////////////
   603    983   
   604    984           private double estimatedCost;
          985  +        /// <summary>
          986  +        /// Estimated cost of using this index.
          987  +        /// </summary>
   605    988           public double EstimatedCost
   606    989           {
   607    990               get { return estimatedCost; }
   608    991               set { estimatedCost = value; }
   609    992           }
   610    993           #endregion
   611    994       }
   612    995       #endregion
   613    996   
   614    997       ///////////////////////////////////////////////////////////////////////////
   615    998   
   616    999       #region SQLiteIndex Helper Class
         1000  +    /// <summary>
         1001  +    /// This class represents the various inputs and outputs used with the
         1002  +    /// <see cref="ISQLiteManagedModule.BestIndex" /> method.
         1003  +    /// </summary>
   617   1004       public sealed class SQLiteIndex
   618   1005       {
   619   1006           #region Internal Constructors
         1007  +        /// <summary>
         1008  +        /// 
         1009  +        /// </summary>
         1010  +        /// <param name="nConstraint">
         1011  +        /// 
         1012  +        /// </param>
         1013  +        /// <param name="nOrderBy">
         1014  +        /// 
         1015  +        /// </param>
   620   1016           internal SQLiteIndex(
   621   1017               int nConstraint,
   622   1018               int nOrderBy
   623   1019               )
   624   1020           {
   625   1021               inputs = new SQLiteIndexInputs(nConstraint, nOrderBy);
   626   1022               outputs = new SQLiteIndexOutputs(nConstraint);
................................................................................
   627   1023           }
   628   1024           #endregion
   629   1025   
   630   1026           ///////////////////////////////////////////////////////////////////////
   631   1027   
   632   1028           #region Public Properties
   633   1029           private SQLiteIndexInputs inputs;
         1030  +        /// <summary>
         1031  +        /// 
         1032  +        /// </summary>
   634   1033           public SQLiteIndexInputs Inputs
   635   1034           {
   636   1035               get { return inputs; }
   637   1036           }
   638   1037   
   639   1038           ///////////////////////////////////////////////////////////////////////
   640   1039   
   641   1040           private SQLiteIndexOutputs outputs;
         1041  +        /// <summary>
         1042  +        /// 
         1043  +        /// </summary>
   642   1044           public SQLiteIndexOutputs Outputs
   643   1045           {
   644   1046               get { return outputs; }
   645   1047           }
   646   1048           #endregion
   647   1049       }
   648   1050       #endregion
................................................................................
   766   1168           }
   767   1169           #endregion
   768   1170   
   769   1171           ///////////////////////////////////////////////////////////////////////
   770   1172   
   771   1173           #region ISQLiteNativeHandle Members
   772   1174           private IntPtr nativeHandle;
         1175  +        /// <summary>
         1176  +        /// Returns the underlying SQLite native handle associated with this
         1177  +        /// object instance.
         1178  +        /// </summary>
   773   1179           public virtual IntPtr NativeHandle
   774   1180           {
   775   1181               get { CheckDisposed(); return nativeHandle; }
   776   1182               internal set { nativeHandle = value; }
   777   1183           }
   778   1184           #endregion
   779   1185   
................................................................................
   924   1330           }
   925   1331           #endregion
   926   1332   
   927   1333           ///////////////////////////////////////////////////////////////////////
   928   1334   
   929   1335           #region ISQLiteNativeHandle Members
   930   1336           private IntPtr nativeHandle;
         1337  +        /// <summary>
         1338  +        /// Returns the underlying SQLite native handle associated with this
         1339  +        /// object instance.
         1340  +        /// </summary>
   931   1341           public virtual IntPtr NativeHandle
   932   1342           {
   933   1343               get { CheckDisposed(); return nativeHandle; }
   934   1344               internal set { nativeHandle = value; }
   935   1345           }
   936   1346           #endregion
   937   1347