System.Data.SQLite

Check-in [3bf2ed2311]
Login

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

Overview
Comment:More work on doc comments.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 3bf2ed2311a4de737830f4601d6e7d0a16cdee0d
User & Date: mistachkin 2017-10-13 21:01:50.659
Context
2017-10-14
02:24
Yet more work on doc comments. check-in: 47a190338f user: mistachkin tags: sessions
2017-10-13
21:01
More work on doc comments. check-in: 3bf2ed2311 user: mistachkin tags: sessions
20:37
Initial work on doc comments. check-in: e1e7276789 user: mistachkin tags: sessions
Changes
Unified Diff Ignore Whitespace Patch
Changes to System.Data.SQLite/SQLiteSession.cs.
282
283
284
285
286
287
288




289
290
291










292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311





312
313
314





315
316
317
318





319
320
321
322
323
324
325



326





327
328
329
330






331
332
333
334
335
336
















337
338
339

340
341
342
343
344

345
346
347
348
349
350
351








352
353
354
355
356
357
358








359
360
361
362
363
364
365







366
367
368
369
370
371
372
        );
    }
    #endregion

    ///////////////////////////////////////////////////////////////////////////

    #region SQLiteSessionHelpers Class




    internal static class SQLiteSessionHelpers
    {
        #region Public Methods










        public static void CheckRawData(
            byte[] rawData
            )
        {
            if (rawData == null)
                throw new ArgumentNullException("rawData");

            if (rawData.Length == 0)
            {
                throw new ArgumentException(
                    "empty change set data", "rawData");
            }
        }
        #endregion
    }
    #endregion

    ///////////////////////////////////////////////////////////////////////////

    #region SQLiteConnectionLock Class





    internal abstract class SQLiteConnectionLock : IDisposable
    {
        #region Private Constants





        private const string LockNopSql = "SELECT 1;";

        ///////////////////////////////////////////////////////////////////////






        private const string StatementMessageFormat =
            "Connection lock object was {0} with statement {1}";
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Private Data



        private SQLiteConnectionHandle handle;





        private SQLiteConnectionFlags flags;

        ///////////////////////////////////////////////////////////////////////







        private IntPtr statement;
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Public Constructors
















        public SQLiteConnectionLock(
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags

            )
        {
            this.handle = handle;
            this.flags = flags;


            Lock();
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Protected Methods








        protected SQLiteConnectionHandle GetHandle()
        {
            return handle;
        }

        ///////////////////////////////////////////////////////////////////////









        protected SQLiteConnectionFlags GetFlags()
        {
            return flags;
        }

        ///////////////////////////////////////////////////////////////////////








        protected IntPtr GetIntPtr()
        {
            if (handle == null)
            {
                throw new InvalidOperationException(
                    "Connection lock object has an invalid handle.");
            }







>
>
>
>



>
>
>
>
>
>
>
>
>
>




















>
>
>
>
>



>
>
>
>
>




>
>
>
>
>







>
>
>

>
>
>
>
>




>
>
>
>
>
>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
>





>
|






>
>
>
>
>
>
>
>







>
>
>
>
>
>
>
>







>
>
>
>
>
>
>







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
        );
    }
    #endregion

    ///////////////////////////////////////////////////////////////////////////

    #region SQLiteSessionHelpers Class
    /// <summary>
    /// This class contains some static helper methods for use within this
    /// subsystem.
    /// </summary>
    internal static class SQLiteSessionHelpers
    {
        #region Public Methods
        /// <summary>
        /// This method checks the byte array specified by the caller to make
        /// sure it will be usable.
        /// </summary>
        /// <param name="rawData">
        /// A byte array provided by the caller into one of the public methods
        /// for the classes that belong to this subsystem.  This value cannot
        /// be null or represent an empty array; otherwise, an appropriate
        /// exception will be thrown.
        /// </param>
        public static void CheckRawData(
            byte[] rawData
            )
        {
            if (rawData == null)
                throw new ArgumentNullException("rawData");

            if (rawData.Length == 0)
            {
                throw new ArgumentException(
                    "empty change set data", "rawData");
            }
        }
        #endregion
    }
    #endregion

    ///////////////////////////////////////////////////////////////////////////

    #region SQLiteConnectionLock Class
    /// <summary>
    /// This class is used to hold the native connection handle associated with
    /// a <see cref="SQLiteConnection" /> open until this subsystem is totally
    /// done with it.  This class is for internal use by this subsystem only.
    /// </summary>
    internal abstract class SQLiteConnectionLock : IDisposable
    {
        #region Private Constants
        /// <summary>
        /// The SQL statement used when creating the native statement handle.
        /// There are no special requirements for this other than counting as
        /// an "open statement handle".
        /// </summary>
        private const string LockNopSql = "SELECT 1;";

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// The format of the error message used when reporting, during object
        /// disposal, that the statement handle is still open (i.e. because
        /// this situation is considered a fairly serious programming error).
        /// </summary>
        private const string StatementMessageFormat =
            "Connection lock object was {0} with statement {1}";
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Private Data
        /// <summary>
        /// The wrapped native connection handle associated with this lock.
        /// </summary>
        private SQLiteConnectionHandle handle;

        /// <summary>
        /// The flags associated with the connection represented by the
        /// <see cref="handle" /> value.
        /// </summary>
        private SQLiteConnectionFlags flags;

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// The native statement handle for this lock.  The garbage collector
        /// cannot cause this statement to be finalized; therefore, it will
        /// serve to hold the associated native connection open until it is
        /// freed manually using the <see cref="Unlock" /> method.
        /// </summary>
        private IntPtr statement;
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Public Constructors
        /// <summary>
        /// Constructs a new instance of this class using the specified native
        /// connection handle and associated flags.
        /// </summary>
        /// <param name="handle">
        /// The wrapped native connection handle to be associated with this
        /// lock.
        /// </param>
        /// <param name="flags">
        /// The flags associated with the connection represented by the
        /// <paramref name="handle" /> value.
        /// </param>
        /// <param name="autoLock">
        /// Non-zero if the <see cref="Lock" /> method should be called prior
        /// to returning from this constructor.
        /// </param>
        public SQLiteConnectionLock(
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags,
            bool autoLock
            )
        {
            this.handle = handle;
            this.flags = flags;

            if (autoLock)
                Lock();
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Protected Methods
        /// <summary>
        /// Queries and returns the wrapped native connection handle for this
        /// instance.
        /// </summary>
        /// <returns>
        /// The wrapped native connection handle for this instance -OR- null
        /// if it is unavailable.
        /// </returns>
        protected SQLiteConnectionHandle GetHandle()
        {
            return handle;
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Queries and returns the flags associated with the connection for
        /// this instance.
        /// </summary>
        /// <returns>
        /// The <see cref="SQLiteConnectionFlags" /> value.  There is no return
        /// value reserved to indicate an error.
        /// </returns>
        protected SQLiteConnectionFlags GetFlags()
        {
            return flags;
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Queries and returns the native connection handle for this instance.
        /// </summary>
        /// <returns>
        /// The native connection handle for this instance.  If this value is
        /// unavailable or invalid an exception will be thrown.
        /// </returns>
        protected IntPtr GetIntPtr()
        {
            if (handle == null)
            {
                throw new InvalidOperationException(
                    "Connection lock object has an invalid handle.");
            }
382
383
384
385
386
387
388








389
390
391
392
393
394
395
            return handlePtr;
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Public Methods








        public void Lock()
        {
            CheckDisposed();

            if (statement != IntPtr.Zero)
                return;








>
>
>
>
>
>
>
>







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
            return handlePtr;
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Public Methods
        /// <summary>
        /// This method attempts to "lock" the associated native connection
        /// handle by preparing a SQL statement that will not be finalized
        /// until the <see cref="Unlock" /> method is called (i.e. and which
        /// cannot be done by the garbage collector).  If the statement is
        /// already prepared, nothing is done.  If the statement cannot be
        /// prepared for any reason, an exception will be thrown.
        /// </summary>
        public void Lock()
        {
            CheckDisposed();

            if (statement != IntPtr.Zero)
                return;

419
420
421
422
423
424
425






426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445



446
447
448
449
450
451
452
453
454
455



456




457
458
459
460
461
462
463
464
465
466
467
468
469







470
471
472
473
474
475
476
                    pSql = IntPtr.Zero;
                }
            }
        }

        ///////////////////////////////////////////////////////////////////////







        public void Unlock()
        {
            CheckDisposed();

            if (statement == IntPtr.Zero)
                return;

            SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_finalize_interop(
                statement);

            if (rc != SQLiteErrorCode.Ok)
                throw new SQLiteException(rc, "sqlite3_finalize_interop");

            statement = IntPtr.Zero;
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region IDisposable Members



        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region IDisposable "Pattern" Members



        private bool disposed;




        private void CheckDisposed() /* throw */
        {
#if THROW_ON_DISPOSED
            if (disposed)
            {
                throw new ObjectDisposedException(
                    typeof(SQLiteConnectionLock).Name);
            }
#endif
        }

        ///////////////////////////////////////////////////////////////////////








        protected virtual void Dispose(bool disposing)
        {
            try
            {
                if (!disposed)
                {
                    //if (disposing)







>
>
>
>
>
>




















>
>
>










>
>
>

>
>
>
>













>
>
>
>
>
>
>







511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
                    pSql = IntPtr.Zero;
                }
            }
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This method attempts to "unlock" the associated native connection
        /// handle by finalizing the previously prepared statement.  If the
        /// statement is already finalized, nothing is done.  If the statement
        /// cannot be finalized for any reason, an exception will be thrown.
        /// </summary>
        public void Unlock()
        {
            CheckDisposed();

            if (statement == IntPtr.Zero)
                return;

            SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_finalize_interop(
                statement);

            if (rc != SQLiteErrorCode.Ok)
                throw new SQLiteException(rc, "sqlite3_finalize_interop");

            statement = IntPtr.Zero;
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region IDisposable Members
        /// <summary>
        /// Disposes of this object instance.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region IDisposable "Pattern" Members
        /// <summary>
        /// Non-zero if this object instance has been disposed.
        /// </summary>
        private bool disposed;

        /// <summary>
        /// Throws an exception if this object instance has been disposed.
        /// </summary>
        private void CheckDisposed() /* throw */
        {
#if THROW_ON_DISPOSED
            if (disposed)
            {
                throw new ObjectDisposedException(
                    typeof(SQLiteConnectionLock).Name);
            }
#endif
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Disposes or finalizes this object instance.
        /// </summary>
        /// <param name="disposing">
        /// Non-zero if this object is being disposed; otherwise, this object
        /// is being finalized.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            try
            {
                if (!disposed)
                {
                    //if (disposing)
525
526
527
528
529
530
531



532
533
534
535
536
537
538
            }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Destructor



        ~SQLiteConnectionLock()
        {
            Dispose(false);
        }
        #endregion
    }
    #endregion







>
>
>







640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
            }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Destructor
        /// <summary>
        /// Finalizes this object instance.
        /// </summary>
        ~SQLiteConnectionLock()
        {
            Dispose(false);
        }
        #endregion
    }
    #endregion
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677

        #region Public Constructors
        public SQLiteSession(
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags,
            string databaseName
            )
            : base(handle, flags)
        {
            this.databaseName = databaseName;

            InitializeHandle();
        }
        #endregion








|







1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795

        #region Public Constructors
        public SQLiteSession(
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags,
            string databaseName
            )
            : base(handle, flags, true)
        {
            this.databaseName = databaseName;

            InitializeHandle();
        }
        #endregion

2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
    internal class SQLiteChangeSetBase : SQLiteConnectionLock
    {
        #region Private Constructors
        internal SQLiteChangeSetBase(
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags
            )
            : base(handle, flags)
        {
            // do nothing.
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////








|







2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
    internal class SQLiteChangeSetBase : SQLiteConnectionLock
    {
        #region Private Constructors
        internal SQLiteChangeSetBase(
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags
            )
            : base(handle, flags, true)
        {
            // do nothing.
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////