System.Data.SQLite
Check-in [8f18f2c045]
Not logged in

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

Overview
Comment:Final work on the initial draft of the doc comments.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 8f18f2c04582b36bc695788a3e8d19e8894b810e
User & Date: mistachkin 2017-10-14 06:37:21
Context
2017-10-14
07:20
Update the master release archive manifest. Closed-Leaf check-in: 71327c1dd6 user: mistachkin tags: sessions
06:37
Final work on the initial draft of the doc comments. check-in: 8f18f2c045 user: mistachkin tags: sessions
04:38
More progress on doc comments. check-in: dfc53a02a6 user: mistachkin tags: sessions
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

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

199
200
201
202
203
204
205



















206












207
208












209
210
211
212
213

















214
215
216
217
218
219
220
....
3163
3164
3165
3166
3167
3168
3169











3170
3171
3172












3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185












3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197



















3198
3199
3200
3201
3202
3203
3204
....
3239
3240
3241
3242
3243
3244
3245



















3246
3247
3248
3249
3250
3251
3252
....
3362
3363
3364
3365
3366
3367
3368



3369
3370
3371
3372






3373
3374
3375
3376
3377
3378















3379
3380
3381
3382
3383
3384
3385
....
3386
3387
3388
3389
3390
3391
3392



















3393
3394
3395
3396
3397
3398
3399
....
3432
3433
3434
3435
3436
3437
3438











3439
3440
3441
3442
3443
3444
3445
....
3504
3505
3506
3507
3508
3509
3510












3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522

















3523
3524
3525
3526
3527
3528
3529
....
3563
3564
3565
3566
3567
3568
3569








3570
3571
3572
3573
3574
3575
3576
3577
3578







3579
3580
3581
3582
3583
3584
3585
....
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
....
3649
3650
3651
3652
3653
3654
3655




3656
3657
3658
3659





3660







3661





3662






3663
3664
3665
3666
3667
3668




















3669
3670
3671
3672
3673
3674
3675
....
3678
3679
3680
3681
3682
3683
3684




3685
3686
3687
3688
3689
3690
3691
....
3695
3696
3697
3698
3699
3700
3701




3702
3703
3704
3705
3706
3707
3708
....
3714
3715
3716
3717
3718
3719
3720



















3721
3722
3723
3724
3725
3726
3727
....
3732
3733
3734
3735
3736
3737
3738











3739
3740
3741
3742
3743
3744
3745
....
3765
3766
3767
3768
3769
3770
3771












3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783

















3784
3785
3786
3787
3788
3789
3790
....
3807
3808
3809
3810
3811
3812
3813








3814
3815
3816
3817
3818
3819
3820
3821
3822
3823







3824
3825
3826
3827
3828
3829
3830
....
3865
3866
3867
3868
3869
3870
3871












3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
....
3897
3898
3899
3900
3901
3902
3903







3904
3905
3906
3907




3908
3909
3910
3911
3912
3913







3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924



3925
3926
3927
3928
3929
3930
3931
3932
3933
3934






3935
3936
3937
3938
3939
3940
3941
3942
3943




3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956







3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968




3969
3970
3971
3972
3973
3974
3975
....
3976
3977
3978
3979
3980
3981
3982




3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994






3995
3996
3997
3998
3999
4000
4001
4002
4003
4004




4005
4006
4007
4008
4009
4010
4011
....
4097
4098
4099
4100
4101
4102
4103




4104
4105
4106
4107






4108
4109
4110
4111
4112
4113








4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125



4126
4127
4128
4129
4130
4131
4132
....
4193
4194
4195
4196
4197
4198
4199





4200
4201
4202
4203










4204
4205
4206
4207
4208
4209
4210
....
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
    /// <summary>
    /// This interface contains methods used to manipulate a set of changes for
    /// a database.
    /// </summary>
    public interface ISQLiteChangeSet :
        IEnumerable<ISQLiteChangeSetMetadataItem>, IDisposable
    {



















        ISQLiteChangeSet Invert();












        ISQLiteChangeSet CombineWith(ISQLiteChangeSet changeSet);













        void Apply(
            SessionConflictCallback conflictCallback,
            object clientData
        );


















        void Apply(
            SessionConflictCallback conflictCallback,
            SessionTableFilterCallback tableFilterCallback,
            object clientData
        );
    }
    #endregion
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteChangeSetBase Class











    internal class SQLiteChangeSetBase : SQLiteConnectionLock
    {
        #region Private Constructors












        internal SQLiteChangeSetBase(
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags
            )
            : base(handle, flags, true)
        {
            // do nothing.
        }
        #endregion

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

        #region Private Methods












        private ISQLiteChangeSetMetadataItem CreateMetadataItem(
            IntPtr iterator
            )
        {
            return new SQLiteChangeSetMetadataItem(
                SQLiteChangeSetIterator.Attach(iterator));
        }
        #endregion

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

        #region Protected Methods



















        protected UnsafeNativeMethods.xSessionFilter GetDelegate(
            SessionTableFilterCallback tableFilterCallback,
            object clientData
            )
        {
            if (tableFilterCallback == null)
                return null;
................................................................................
            });

            return xFilter;
        }

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




















        protected UnsafeNativeMethods.xSessionConflict GetDelegate(
            SessionConflictCallback conflictCallback,
            object clientData
            )
        {
            if (conflictCallback == null)
                return null;
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteMemoryChangeSet Class



    internal sealed class SQLiteMemoryChangeSet :
        SQLiteChangeSetBase, ISQLiteChangeSet
    {
        #region Private Data






        private byte[] rawData;
        #endregion

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

        #region Private Constructors















        internal SQLiteMemoryChangeSet(
            byte[] rawData,
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags
            )
            : base(handle, flags)
        {
................................................................................
            this.rawData = rawData;
        }
        #endregion

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

        #region ISQLiteChangeSet Members



















        public ISQLiteChangeSet Invert()
        {
            CheckDisposed();

            SQLiteSessionHelpers.CheckRawData(rawData);

            IntPtr pInData = IntPtr.Zero;
................................................................................
                    pInData = IntPtr.Zero;
                }
            }
        }

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












        public ISQLiteChangeSet CombineWith(
            ISQLiteChangeSet changeSet
            )
        {
            CheckDisposed();

            SQLiteSessionHelpers.CheckRawData(rawData);
................................................................................
                    pInData1 = IntPtr.Zero;
                }
            }
        }

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













        public void Apply(
            SessionConflictCallback conflictCallback,
            object clientData
            )
        {
            CheckDisposed();

            Apply(conflictCallback, null, clientData);
        }

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


















        public void Apply(
            SessionConflictCallback conflictCallback,
            SessionTableFilterCallback tableFilterCallback,
            object clientData
            )
        {
            CheckDisposed();
................................................................................
            }
        }
        #endregion

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

        #region IEnumerable<ISQLiteChangeSetMetadataItem> Members








        public IEnumerator<ISQLiteChangeSetMetadataItem> GetEnumerator()
        {
            return new SQLiteMemoryChangeSetEnumerator(rawData);
        }
        #endregion

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

        #region IEnumerable Members







        IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////
................................................................................
                        if (rawData != null)
                            rawData = null;
                    }

                    //////////////////////////////////////
                    // release unmanaged resources here...
                    //////////////////////////////////////

                    Unlock();
                }
            }
            finally
            {
                base.Dispose(disposing);

                //
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteStreamChangeSet Class




    internal sealed class SQLiteStreamChangeSet :
        SQLiteChangeSetBase, ISQLiteChangeSet
    {
        #region Private Data





        private SQLiteStreamAdapter inputStreamAdapter;







        private SQLiteStreamAdapter outputStreamAdapter;





        private Stream inputStream;






        private Stream outputStream;
        #endregion

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

        #region Private Constructors




















        internal SQLiteStreamChangeSet(
            Stream inputStream,
            Stream outputStream,
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags
            )
            : base(handle, flags)
................................................................................
            this.outputStream = outputStream;
        }
        #endregion

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

        #region Private Methods




        private void CheckInputStream()
        {
            if (inputStream == null)
            {
                throw new InvalidOperationException(
                    "input stream unavailable");
            }
................................................................................
                inputStreamAdapter = new SQLiteStreamAdapter(
                    inputStream, GetFlags());
            }
        }

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





        private void CheckOutputStream()
        {
            if (outputStream == null)
            {
                throw new InvalidOperationException(
                    "output stream unavailable");
            }
................................................................................
            }
        }
        #endregion

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

        #region ISQLiteChangeSet Members



















        public ISQLiteChangeSet Invert()
        {
            CheckDisposed();
            CheckInputStream();
            CheckOutputStream();

            SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changeset_invert_strm(
................................................................................
                throw new SQLiteException(rc, "sqlite3changeset_invert_strm");

            return null;
        }

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












        public ISQLiteChangeSet CombineWith(
            ISQLiteChangeSet changeSet
            )
        {
            CheckDisposed();
            CheckInputStream();
            CheckOutputStream();
................................................................................
                throw new SQLiteException(rc, "sqlite3changeset_concat_strm");

            return null;
        }

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













        public void Apply(
            SessionConflictCallback conflictCallback,
            object clientData
            )
        {
            CheckDisposed();

            Apply(conflictCallback, null, clientData);
        }

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


















        public void Apply(
            SessionConflictCallback conflictCallback,
            SessionTableFilterCallback tableFilterCallback,
            object clientData
            )
        {
            CheckDisposed();
................................................................................
                throw new SQLiteException(rc, "sqlite3changeset_apply_strm");
        }
        #endregion

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

        #region IEnumerable<ISQLiteChangeSetMetadataItem> Members








        public IEnumerator<ISQLiteChangeSetMetadataItem> GetEnumerator()
        {
            return new SQLiteStreamChangeSetEnumerator(
                inputStream, GetFlags());
        }
        #endregion

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

        #region IEnumerable Members







        IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////
................................................................................
                if (!disposed)
                {
                    if (disposing)
                    {
                        ////////////////////////////////////
                        // dispose managed resources here...
                        ////////////////////////////////////













                        if (outputStream != null)
                            outputStream = null; /* NOT OWNED */

                        if (inputStream != null)
                            inputStream = null; /* NOT OWNED */
                    }

                    //////////////////////////////////////
                    // release unmanaged resources here...
                    //////////////////////////////////////

                    Unlock();
                }
            }
            finally
            {
                base.Dispose(disposing);

                //
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteChangeSetEnumerator Class







    internal abstract class SQLiteChangeSetEnumerator :
        IEnumerator<ISQLiteChangeSetMetadataItem>
    {
        #region Private Data




        private SQLiteChangeSetIterator iterator;
        #endregion

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

        #region Public Constructors







        public SQLiteChangeSetEnumerator(
            SQLiteChangeSetIterator iterator
            )
        {
            SetIterator(iterator);
        }
        #endregion

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

        #region Private Methods



        private void CheckIterator()
        {
            if (iterator == null)
                throw new InvalidOperationException("iterator unavailable");

            iterator.CheckHandle();
        }

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







        private void SetIterator(
            SQLiteChangeSetIterator iterator
            )
        {
            this.iterator = iterator;
        }

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





        private void CloseIterator()
        {
            if (iterator != null)
            {
                iterator.Dispose();
                iterator = null;
            }
        }
        #endregion

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

        #region Protected Methods







        protected void ResetIterator(
            SQLiteChangeSetIterator iterator
            )
        {
            CloseIterator();
            SetIterator(iterator);
        }
        #endregion

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

        #region IEnumerator<ISQLiteChangeSetMetadataItem> Members




        public ISQLiteChangeSetMetadataItem Current
        {
            get
            {
                CheckDisposed();

                return new SQLiteChangeSetMetadataItem(iterator);
................................................................................
            }
        }
        #endregion

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

        #region IEnumerator Members




        object Collections.IEnumerator.Current
        {
            get
            {
                CheckDisposed();

                return Current;
            }
        }

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







        public bool MoveNext()
        {
            CheckDisposed();
            CheckIterator();

            return iterator.Next();
        }

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





        public virtual void Reset()
        {
            CheckDisposed();

            throw new NotImplementedException();
        }
        #endregion
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteMemoryChangeSetEnumerator Class




    internal sealed class SQLiteMemoryChangeSetEnumerator :
        SQLiteChangeSetEnumerator
    {
        #region Private Data






        private byte[] rawData;
        #endregion

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

        #region Public Constructors








        public SQLiteMemoryChangeSetEnumerator(
            byte[] rawData
            )
            : base(SQLiteMemoryChangeSetIterator.Create(rawData))
        {
            this.rawData = rawData;
        }
        #endregion

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

        #region IEnumerator Overrides



        public override void Reset()
        {
            CheckDisposed();

            ResetIterator(SQLiteMemoryChangeSetIterator.Create(rawData));
        }
        #endregion
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteStreamChangeSetEnumerator Class





    internal sealed class SQLiteStreamChangeSetEnumerator :
        SQLiteChangeSetEnumerator
    {
        #region Public Constructors










        public SQLiteStreamChangeSetEnumerator(
            Stream stream,
            SQLiteConnectionFlags flags
            )
            : base(SQLiteStreamChangeSetIterator.Create(stream, flags))
        {
            // do nothing.
................................................................................

        #region Public Constructors
        /// <summary>
        /// Constructs an instance of this class using the specified iterator
        /// instance.
        /// </summary>
        /// <param name="iterator">
        /// The native iterator handle to use.
        /// </param>
        public SQLiteChangeSetMetadataItem(
            SQLiteChangeSetIterator iterator
            )
        {
            this.iterator = iterator;
        }







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

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


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





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







 







>
>
>
>
>
>
>
>
>
>
>



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













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












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







 







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







 







>
>
>




>
>
>
>
>
>






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







 







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







 







>
>
>
>
>
>
>
>
>
>
>







 







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












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







 







>
>
>
>
>
>
>
>









>
>
>
>
>
>
>







 







<
<







 







>
>
>
>




>
>
>
>
>

>
>
>
>
>
>
>

>
>
>
>
>

>
>
>
>
>
>






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







 







>
>
>
>







 







>
>
>
>







 







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







 







>
>
>
>
>
>
>
>
>
>
>







 







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












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







 







>
>
>
>
>
>
>
>










>
>
>
>
>
>
>







 







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











<
<







 







>
>
>
>
>
>
>




>
>
>
>






>
>
>
>
>
>
>











>
>
>










>
>
>
>
>
>









>
>
>
>













>
>
>
>
>
>
>












>
>
>
>







 







>
>
>
>












>
>
>
>
>
>










>
>
>
>







 







>
>
>
>




>
>
>
>
>
>






>
>
>
>
>
>
>
>












>
>
>







 







>
>
>
>
>




>
>
>
>
>
>
>
>
>
>







 







|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
....
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
....
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
....
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
....
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
....
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
....
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
....
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
....
3859
3860
3861
3862
3863
3864
3865


3866
3867
3868
3869
3870
3871
3872
....
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
....
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
....
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
....
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
....
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
....
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
....
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
....
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252


4253
4254
4255
4256
4257
4258
4259
....
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
....
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
....
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
....
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
....
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
    /// <summary>
    /// This interface contains methods used to manipulate a set of changes for
    /// a database.
    /// </summary>
    public interface ISQLiteChangeSet :
        IEnumerable<ISQLiteChangeSetMetadataItem>, IDisposable
    {
        /// <summary>
        /// This method "inverts" the set of changes within this instance.
        /// Applying an inverted set of changes to a database reverses the
        /// effects of applying the uninverted changes.  Specifically:
        /// <![CDATA[<ul>]]><![CDATA[<li>]]>
        /// Each DELETE change is changed to an INSERT, and
        /// <![CDATA[</li>]]><![CDATA[<li>]]>
        /// Each INSERT change is changed to a DELETE, and
        /// <![CDATA[</li>]]><![CDATA[<li>]]>
        /// For each UPDATE change, the old.* and new.* values are exchanged.
        /// <![CDATA[</li>]]><![CDATA[</ul>]]>
        /// This method does not change the order in which changes appear
        /// within the set of changes. It merely reverses the sense of each
        /// individual change.
        /// </summary>
        /// <returns>
        /// The new <see cref="ISQLiteChangeSet" /> instance that represents
        /// the resulting set of changes -OR- null if it is not available.
        /// </returns>
        ISQLiteChangeSet Invert();

        /// <summary>
        /// This method combines the specified set of changes with the ones
        /// contained in this instance.
        /// </summary>
        /// <param name="changeSet">
        /// The changes to be combined with those in this instance.
        /// </param>
        /// <returns>
        /// The new <see cref="ISQLiteChangeSet" /> instance that represents
        /// the resulting set of changes -OR- null if it is not available.
        /// </returns>
        ISQLiteChangeSet CombineWith(ISQLiteChangeSet changeSet);

        /// <summary>
        /// Attempts to apply the set of changes in this instance to the
        /// associated database.
        /// </summary>
        /// <param name="conflictCallback">
        /// The <see cref="SessionConflictCallback" /> delegate that will need
        /// to handle any conflicting changes that may arise.
        /// </param>
        /// <param name="clientData">
        /// The optional application-defined context data.  This value may be
        /// null.
        /// </param>
        void Apply(
            SessionConflictCallback conflictCallback,
            object clientData
        );

        /// <summary>
        /// Attempts to apply the set of changes in this instance to the
        /// associated database.
        /// </summary>
        /// <param name="conflictCallback">
        /// The <see cref="SessionConflictCallback" /> delegate that will need
        /// to handle any conflicting changes that may arise.
        /// </param>
        /// <param name="tableFilterCallback">
        /// The optional <see cref="SessionTableFilterCallback" /> delegate
        /// that can be used to filter the list of tables impacted by the set
        /// of changes.
        /// </param>
        /// <param name="clientData">
        /// The optional application-defined context data.  This value may be
        /// null.
        /// </param>
        void Apply(
            SessionConflictCallback conflictCallback,
            SessionTableFilterCallback tableFilterCallback,
            object clientData
        );
    }
    #endregion
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteChangeSetBase Class
    /// <summary>
    /// This class represents the abstract concept of a set of changes.  It
    /// acts as the base class for the <see cref="SQLiteMemoryChangeSet" />
    /// and <see cref="SQLiteStreamChangeSet" /> classes.  It derives from
    /// the <see cref="SQLiteConnectionLock" /> class, which is used to hold
    /// the underlying native connection handle open until the instances of
    /// this class are disposed or finalized.  It also provides the ability
    /// to construct wrapped native delegates of the
    /// <see cref="UnsafeNativeMethods.xSessionFilter" /> and
    /// <see cref="UnsafeNativeMethods.xSessionConflict" /> types.
    /// </summary>
    internal class SQLiteChangeSetBase : SQLiteConnectionLock
    {
        #region Private Constructors
        /// <summary>
        /// Constructs an instance of this class using the specified wrapped
        /// native connection handle.
        /// </summary>
        /// <param name="handle">
        /// The wrapped native connection handle to be associated with this
        /// change set.
        /// </param>
        /// <param name="flags">
        /// The flags associated with the connection represented by the
        /// <paramref name="handle" /> value.
        /// </param>
        internal SQLiteChangeSetBase(
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags
            )
            : base(handle, flags, true)
        {
            // do nothing.
        }
        #endregion

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

        #region Private Methods
        /// <summary>
        /// Creates and returns a concrete implementation of the
        /// <see cref="ISQLiteChangeSetMetadataItem" /> interface.
        /// </summary>
        /// <param name="iterator">
        /// The native iterator handle to use.
        /// </param>
        /// <returns>
        /// An instance of the <see cref="ISQLiteChangeSetMetadataItem"/>
        /// interface, which can be used to fetch metadata associated with
        /// the current item in this set of changes.
        /// </returns>
        private ISQLiteChangeSetMetadataItem CreateMetadataItem(
            IntPtr iterator
            )
        {
            return new SQLiteChangeSetMetadataItem(
                SQLiteChangeSetIterator.Attach(iterator));
        }
        #endregion

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

        #region Protected Methods
        /// <summary>
        /// Attempts to create a
        /// <see cref="UnsafeNativeMethods.xSessionFilter" /> native delegate
        /// that invokes the specified
        /// <see cref="SessionTableFilterCallback" /> delegate.
        /// </summary>
        /// <param name="tableFilterCallback">
        /// The <see cref="SessionTableFilterCallback" /> to invoke when the
        /// <see cref="UnsafeNativeMethods.xSessionFilter" /> native delegate
        /// is called.  If this value is null then null is returned.
        /// </param>
        /// <param name="clientData">
        /// The optional application-defined context data.  This value may be
        /// null.
        /// </param>
        /// <returns>
        /// The created <see cref="UnsafeNativeMethods.xSessionFilter" />
        /// native delegate -OR- null if it cannot be created.
        /// </returns>
        protected UnsafeNativeMethods.xSessionFilter GetDelegate(
            SessionTableFilterCallback tableFilterCallback,
            object clientData
            )
        {
            if (tableFilterCallback == null)
                return null;
................................................................................
            });

            return xFilter;
        }

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

        /// <summary>
        /// Attempts to create a
        /// <see cref="UnsafeNativeMethods.xSessionConflict" /> native delegate
        /// that invokes the specified
        /// <see cref="SessionConflictCallback" /> delegate.
        /// </summary>
        /// <param name="conflictCallback">
        /// The <see cref="SessionConflictCallback" /> to invoke when the
        /// <see cref="UnsafeNativeMethods.xSessionConflict" /> native delegate
        /// is called.  If this value is null then null is returned.
        /// </param>
        /// <param name="clientData">
        /// The optional application-defined context data.  This value may be
        /// null.
        /// </param>
        /// <returns>
        /// The created <see cref="UnsafeNativeMethods.xSessionConflict" />
        /// native delegate -OR- null if it cannot be created.
        /// </returns>
        protected UnsafeNativeMethods.xSessionConflict GetDelegate(
            SessionConflictCallback conflictCallback,
            object clientData
            )
        {
            if (conflictCallback == null)
                return null;
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteMemoryChangeSet Class
    /// <summary>
    /// This class represents a set of changes contained entirely in memory.
    /// </summary>
    internal sealed class SQLiteMemoryChangeSet :
        SQLiteChangeSetBase, ISQLiteChangeSet
    {
        #region Private Data
        /// <summary>
        /// The raw byte data for this set of changes.  Since this data must
        /// be marshalled to a native memory buffer before being used, there
        /// must be enough memory available to store at least two times the
        /// amount of data contained within it.
        /// </summary>
        private byte[] rawData;
        #endregion

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

        #region Private Constructors
        /// <summary>
        /// Constructs an instance of this class using the specified raw byte
        /// data and wrapped native connection handle.
        /// </summary>
        /// <param name="rawData">
        /// The raw byte data for the specified change set (or patch set).
        /// </param>
        /// <param name="handle">
        /// The wrapped native connection handle to be associated with this
        /// set of changes.
        /// </param>
        /// <param name="flags">
        /// The flags associated with the connection represented by the
        /// <paramref name="handle" /> value.
        /// </param>
        internal SQLiteMemoryChangeSet(
            byte[] rawData,
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags
            )
            : base(handle, flags)
        {
................................................................................
            this.rawData = rawData;
        }
        #endregion

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

        #region ISQLiteChangeSet Members
        /// <summary>
        /// This method "inverts" the set of changes within this instance.
        /// Applying an inverted set of changes to a database reverses the
        /// effects of applying the uninverted changes.  Specifically:
        /// <![CDATA[<ul>]]><![CDATA[<li>]]>
        /// Each DELETE change is changed to an INSERT, and
        /// <![CDATA[</li>]]><![CDATA[<li>]]>
        /// Each INSERT change is changed to a DELETE, and
        /// <![CDATA[</li>]]><![CDATA[<li>]]>
        /// For each UPDATE change, the old.* and new.* values are exchanged.
        /// <![CDATA[</li>]]><![CDATA[</ul>]]>
        /// This method does not change the order in which changes appear
        /// within the set of changes. It merely reverses the sense of each
        /// individual change.
        /// </summary>
        /// <returns>
        /// The new <see cref="ISQLiteChangeSet" /> instance that represents
        /// the resulting set of changes.
        /// </returns>
        public ISQLiteChangeSet Invert()
        {
            CheckDisposed();

            SQLiteSessionHelpers.CheckRawData(rawData);

            IntPtr pInData = IntPtr.Zero;
................................................................................
                    pInData = IntPtr.Zero;
                }
            }
        }

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

        /// <summary>
        /// This method combines the specified set of changes with the ones
        /// contained in this instance.
        /// </summary>
        /// <param name="changeSet">
        /// The changes to be combined with those in this instance.
        /// </param>
        /// <returns>
        /// The new <see cref="ISQLiteChangeSet" /> instance that represents
        /// the resulting set of changes.
        /// </returns>
        public ISQLiteChangeSet CombineWith(
            ISQLiteChangeSet changeSet
            )
        {
            CheckDisposed();

            SQLiteSessionHelpers.CheckRawData(rawData);
................................................................................
                    pInData1 = IntPtr.Zero;
                }
            }
        }

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

        /// <summary>
        /// Attempts to apply the set of changes in this instance to the
        /// associated database.
        /// </summary>
        /// <param name="conflictCallback">
        /// The <see cref="SessionConflictCallback" /> delegate that will need
        /// to handle any conflicting changes that may arise.
        /// </param>
        /// <param name="clientData">
        /// The optional application-defined context data.  This value may be
        /// null.
        /// </param>
        public void Apply(
            SessionConflictCallback conflictCallback,
            object clientData
            )
        {
            CheckDisposed();

            Apply(conflictCallback, null, clientData);
        }

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

        /// <summary>
        /// Attempts to apply the set of changes in this instance to the
        /// associated database.
        /// </summary>
        /// <param name="conflictCallback">
        /// The <see cref="SessionConflictCallback" /> delegate that will need
        /// to handle any conflicting changes that may arise.
        /// </param>
        /// <param name="tableFilterCallback">
        /// The optional <see cref="SessionTableFilterCallback" /> delegate
        /// that can be used to filter the list of tables impacted by the set
        /// of changes.
        /// </param>
        /// <param name="clientData">
        /// The optional application-defined context data.  This value may be
        /// null.
        /// </param>
        public void Apply(
            SessionConflictCallback conflictCallback,
            SessionTableFilterCallback tableFilterCallback,
            object clientData
            )
        {
            CheckDisposed();
................................................................................
            }
        }
        #endregion

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

        #region IEnumerable<ISQLiteChangeSetMetadataItem> Members
        /// <summary>
        /// Creates an <see cref="IEnumerator" /> capable of iterating over the
        /// items within this set of changes.
        /// </summary>
        /// <returns>
        /// The new <see cref="IEnumerator{ISQLiteChangeSetMetadataItem}" />
        /// instance.
        /// </returns>
        public IEnumerator<ISQLiteChangeSetMetadataItem> GetEnumerator()
        {
            return new SQLiteMemoryChangeSetEnumerator(rawData);
        }
        #endregion

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

        #region IEnumerable Members
        /// <summary>
        /// Creates an <see cref="IEnumerator" /> capable of iterating over the
        /// items within this set of changes.
        /// </summary>
        /// <returns>
        /// The new <see cref="IEnumerator" /> instance.
        /// </returns>
        IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////
................................................................................
                        if (rawData != null)
                            rawData = null;
                    }

                    //////////////////////////////////////
                    // release unmanaged resources here...
                    //////////////////////////////////////


                }
            }
            finally
            {
                base.Dispose(disposing);

                //
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteStreamChangeSet Class
    /// <summary>
    /// This class represents a set of changes that are backed by a
    /// <see cref="Stream" /> instance.
    /// </summary>
    internal sealed class SQLiteStreamChangeSet :
        SQLiteChangeSetBase, ISQLiteChangeSet
    {
        #region Private Data
        /// <summary>
        /// The <see cref="SQLiteStreamAdapter" /> instance that is managing
        /// the underlying input <see cref="Stream" /> used as the backing
        /// store for the set of changes associated with this instance.
        /// </summary>
        private SQLiteStreamAdapter inputStreamAdapter;

        /// <summary>
        /// The <see cref="SQLiteStreamAdapter" /> instance that is managing
        /// the underlying output <see cref="Stream" /> used as the backing
        /// store for the set of changes generated by the <see cref="Invert" />
        /// or <see cref="CombineWith" /> methods.
        /// </summary>
        private SQLiteStreamAdapter outputStreamAdapter;

        /// <summary>
        /// The <see cref="Stream" /> instance used as the backing store for
        /// the set of changes associated with this instance.
        /// </summary>
        private Stream inputStream;

        /// <summary>
        /// The <see cref="Stream" /> instance used as the backing store for
        /// the set of changes generated by the <see cref="Invert" /> or
        /// <see cref="CombineWith" /> methods.
        /// </summary>
        private Stream outputStream;
        #endregion

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

        #region Private Constructors
        /// <summary>
        /// Constructs an instance of this class using the specified streams
        /// and wrapped native connection handle.
        /// </summary>
        /// <param name="inputStream">
        /// The <see cref="Stream" /> where the raw byte data for the set of
        /// changes may be read.
        /// </param>
        /// <param name="outputStream">
        /// The <see cref="Stream" /> where the raw byte data for resulting
        /// sets of changes may be written.
        /// </param>
        /// <param name="handle">
        /// The wrapped native connection handle to be associated with this
        /// set of changes.
        /// </param>
        /// <param name="flags">
        /// The flags associated with the connection represented by the
        /// <paramref name="handle" /> value.
        /// </param>
        internal SQLiteStreamChangeSet(
            Stream inputStream,
            Stream outputStream,
            SQLiteConnectionHandle handle,
            SQLiteConnectionFlags flags
            )
            : base(handle, flags)
................................................................................
            this.outputStream = outputStream;
        }
        #endregion

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

        #region Private Methods
        /// <summary>
        /// Throws an exception if the input stream or its associated stream
        /// adapter are invalid.
        /// </summary>
        private void CheckInputStream()
        {
            if (inputStream == null)
            {
                throw new InvalidOperationException(
                    "input stream unavailable");
            }
................................................................................
                inputStreamAdapter = new SQLiteStreamAdapter(
                    inputStream, GetFlags());
            }
        }

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

        /// <summary>
        /// Throws an exception if the output stream or its associated stream
        /// adapter are invalid.
        /// </summary>
        private void CheckOutputStream()
        {
            if (outputStream == null)
            {
                throw new InvalidOperationException(
                    "output stream unavailable");
            }
................................................................................
            }
        }
        #endregion

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

        #region ISQLiteChangeSet Members
        /// <summary>
        /// This method "inverts" the set of changes within this instance.
        /// Applying an inverted set of changes to a database reverses the
        /// effects of applying the uninverted changes.  Specifically:
        /// <![CDATA[<ul>]]><![CDATA[<li>]]>
        /// Each DELETE change is changed to an INSERT, and
        /// <![CDATA[</li>]]><![CDATA[<li>]]>
        /// Each INSERT change is changed to a DELETE, and
        /// <![CDATA[</li>]]><![CDATA[<li>]]>
        /// For each UPDATE change, the old.* and new.* values are exchanged.
        /// <![CDATA[</li>]]><![CDATA[</ul>]]>
        /// This method does not change the order in which changes appear
        /// within the set of changes. It merely reverses the sense of each
        /// individual change.
        /// </summary>
        /// <returns>
        /// Since the resulting set of changes is written to the output stream,
        /// this method always returns null.
        /// </returns>
        public ISQLiteChangeSet Invert()
        {
            CheckDisposed();
            CheckInputStream();
            CheckOutputStream();

            SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changeset_invert_strm(
................................................................................
                throw new SQLiteException(rc, "sqlite3changeset_invert_strm");

            return null;
        }

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

        /// <summary>
        /// This method combines the specified set of changes with the ones
        /// contained in this instance.
        /// </summary>
        /// <param name="changeSet">
        /// The changes to be combined with those in this instance.
        /// </param>
        /// <returns>
        /// Since the resulting set of changes is written to the output stream,
        /// this method always returns null.
        /// </returns>
        public ISQLiteChangeSet CombineWith(
            ISQLiteChangeSet changeSet
            )
        {
            CheckDisposed();
            CheckInputStream();
            CheckOutputStream();
................................................................................
                throw new SQLiteException(rc, "sqlite3changeset_concat_strm");

            return null;
        }

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

        /// <summary>
        /// Attempts to apply the set of changes in this instance to the
        /// associated database.
        /// </summary>
        /// <param name="conflictCallback">
        /// The <see cref="SessionConflictCallback" /> delegate that will need
        /// to handle any conflicting changes that may arise.
        /// </param>
        /// <param name="clientData">
        /// The optional application-defined context data.  This value may be
        /// null.
        /// </param>
        public void Apply(
            SessionConflictCallback conflictCallback,
            object clientData
            )
        {
            CheckDisposed();

            Apply(conflictCallback, null, clientData);
        }

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

        /// <summary>
        /// Attempts to apply the set of changes in this instance to the
        /// associated database.
        /// </summary>
        /// <param name="conflictCallback">
        /// The <see cref="SessionConflictCallback" /> delegate that will need
        /// to handle any conflicting changes that may arise.
        /// </param>
        /// <param name="tableFilterCallback">
        /// The optional <see cref="SessionTableFilterCallback" /> delegate
        /// that can be used to filter the list of tables impacted by the set
        /// of changes.
        /// </param>
        /// <param name="clientData">
        /// The optional application-defined context data.  This value may be
        /// null.
        /// </param>
        public void Apply(
            SessionConflictCallback conflictCallback,
            SessionTableFilterCallback tableFilterCallback,
            object clientData
            )
        {
            CheckDisposed();
................................................................................
                throw new SQLiteException(rc, "sqlite3changeset_apply_strm");
        }
        #endregion

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

        #region IEnumerable<ISQLiteChangeSetMetadataItem> Members
        /// <summary>
        /// Creates an <see cref="IEnumerator" /> capable of iterating over the
        /// items within this set of changes.
        /// </summary>
        /// <returns>
        /// The new <see cref="IEnumerator{ISQLiteChangeSetMetadataItem}" />
        /// instance.
        /// </returns>
        public IEnumerator<ISQLiteChangeSetMetadataItem> GetEnumerator()
        {
            return new SQLiteStreamChangeSetEnumerator(
                inputStream, GetFlags());
        }
        #endregion

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

        #region IEnumerable Members
        /// <summary>
        /// Creates an <see cref="IEnumerator" /> capable of iterating over the
        /// items within this set of changes.
        /// </summary>
        /// <returns>
        /// The new <see cref="IEnumerator" /> instance.
        /// </returns>
        IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////
................................................................................
                if (!disposed)
                {
                    if (disposing)
                    {
                        ////////////////////////////////////
                        // dispose managed resources here...
                        ////////////////////////////////////

                        if (outputStreamAdapter != null)
                        {
                            outputStreamAdapter.Dispose();
                            outputStreamAdapter = null;
                        }

                        if (inputStreamAdapter != null)
                        {
                            inputStreamAdapter.Dispose();
                            inputStreamAdapter = null;
                        }

                        if (outputStream != null)
                            outputStream = null; /* NOT OWNED */

                        if (inputStream != null)
                            inputStream = null; /* NOT OWNED */
                    }

                    //////////////////////////////////////
                    // release unmanaged resources here...
                    //////////////////////////////////////


                }
            }
            finally
            {
                base.Dispose(disposing);

                //
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteChangeSetEnumerator Class
    /// <summary>
    /// This class represents an <see cref="IEnumerator" /> that is capable of
    /// enumerating over a set of changes.  It serves as the base class for the
    /// <see cref="SQLiteMemoryChangeSetEnumerator" /> and
    /// <see cref="SQLiteStreamChangeSetEnumerator" /> classes.  It manages and
    /// owns an instance of the <see cref="SQLiteChangeSetIterator" /> class.
    /// </summary>
    internal abstract class SQLiteChangeSetEnumerator :
        IEnumerator<ISQLiteChangeSetMetadataItem>
    {
        #region Private Data
        /// <summary>
        /// This managed change set iterator is managed and owned by this
        /// class.  It will be disposed when this class is disposed.
        /// </summary>
        private SQLiteChangeSetIterator iterator;
        #endregion

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

        #region Public Constructors
        /// <summary>
        /// Constructs an instance of this class using the specified managed
        /// change set iterator.
        /// </summary>
        /// <param name="iterator">
        /// The managed iterator instance to use.
        /// </param>
        public SQLiteChangeSetEnumerator(
            SQLiteChangeSetIterator iterator
            )
        {
            SetIterator(iterator);
        }
        #endregion

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

        #region Private Methods
        /// <summary>
        /// Throws an exception if the managed iterator instance is invalid.
        /// </summary>
        private void CheckIterator()
        {
            if (iterator == null)
                throw new InvalidOperationException("iterator unavailable");

            iterator.CheckHandle();
        }

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

        /// <summary>
        /// Sets the managed iterator instance to a new value.
        /// </summary>
        /// <param name="iterator">
        /// The new managed iterator instance to use.
        /// </param>
        private void SetIterator(
            SQLiteChangeSetIterator iterator
            )
        {
            this.iterator = iterator;
        }

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

        /// <summary>
        /// Disposes of the managed iterator instance and sets its value to
        /// null.
        /// </summary>
        private void CloseIterator()
        {
            if (iterator != null)
            {
                iterator.Dispose();
                iterator = null;
            }
        }
        #endregion

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

        #region Protected Methods
        /// <summary>
        /// Disposes of the existing managed iterator instance and then sets it
        /// to a new value.
        /// </summary>
        /// <param name="iterator">
        /// The new managed iterator instance to use.
        /// </param>
        protected void ResetIterator(
            SQLiteChangeSetIterator iterator
            )
        {
            CloseIterator();
            SetIterator(iterator);
        }
        #endregion

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

        #region IEnumerator<ISQLiteChangeSetMetadataItem> Members
        /// <summary>
        /// Returns the current change within the set of changes, represented
        /// by a <see cref="ISQLiteChangeSetMetadataItem" /> instance.
        /// </summary>
        public ISQLiteChangeSetMetadataItem Current
        {
            get
            {
                CheckDisposed();

                return new SQLiteChangeSetMetadataItem(iterator);
................................................................................
            }
        }
        #endregion

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

        #region IEnumerator Members
        /// <summary>
        /// Returns the current change within the set of changes, represented
        /// by a <see cref="ISQLiteChangeSetMetadataItem" /> instance.
        /// </summary>
        object Collections.IEnumerator.Current
        {
            get
            {
                CheckDisposed();

                return Current;
            }
        }

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

        /// <summary>
        /// Attempts to advance to the next item in the set of changes.
        /// </summary>
        /// <returns>
        /// Non-zero if more items are available; otherwise, zero.
        /// </returns>
        public bool MoveNext()
        {
            CheckDisposed();
            CheckIterator();

            return iterator.Next();
        }

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

        /// <summary>
        /// Throws <see cref="NotImplementedException" /> because not all the
        /// derived classes are able to support reset functionality.
        /// </summary>
        public virtual void Reset()
        {
            CheckDisposed();

            throw new NotImplementedException();
        }
        #endregion
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteMemoryChangeSetEnumerator Class
    /// <summary>
    /// This class represents an <see cref="IEnumerator" /> that is capable of
    /// enumerating over a set of changes contained entirely in memory.
    /// </summary>
    internal sealed class SQLiteMemoryChangeSetEnumerator :
        SQLiteChangeSetEnumerator
    {
        #region Private Data
        /// <summary>
        /// The raw byte data for this set of changes.  Since this data must
        /// be marshalled to a native memory buffer before being used, there
        /// must be enough memory available to store at least two times the
        /// amount of data contained within it.
        /// </summary>
        private byte[] rawData;
        #endregion

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

        #region Public Constructors
        /// <summary>
        /// Constructs an instance of this class using the specified raw byte
        /// data.
        /// </summary>
        /// <param name="rawData">
        /// The raw byte data containing the set of changes for this
        /// enumerator.
        /// </param>
        public SQLiteMemoryChangeSetEnumerator(
            byte[] rawData
            )
            : base(SQLiteMemoryChangeSetIterator.Create(rawData))
        {
            this.rawData = rawData;
        }
        #endregion

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

        #region IEnumerator Overrides
        /// <summary>
        /// Resets the enumerator to its initial position.
        /// </summary>
        public override void Reset()
        {
            CheckDisposed();

            ResetIterator(SQLiteMemoryChangeSetIterator.Create(rawData));
        }
        #endregion
................................................................................
        #endregion
    }
    #endregion

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

    #region SQLiteStreamChangeSetEnumerator Class
    /// <summary>
    /// This class represents an <see cref="IEnumerator" /> that is capable of
    /// enumerating over a set of changes backed by a <see cref="Stream" />
    /// instance.
    /// </summary>
    internal sealed class SQLiteStreamChangeSetEnumerator :
        SQLiteChangeSetEnumerator
    {
        #region Public Constructors
        /// <summary>
        /// Constructs an instance of this class using the specified stream.
        /// </summary>
        /// <param name="stream">
        /// The <see cref="Stream" /> where the raw byte data for the set of
        /// changes may be read.
        /// </param>
        /// <param name="flags">
        /// The flags associated with the parent connection.
        /// </param>
        public SQLiteStreamChangeSetEnumerator(
            Stream stream,
            SQLiteConnectionFlags flags
            )
            : base(SQLiteStreamChangeSetIterator.Create(stream, flags))
        {
            // do nothing.
................................................................................

        #region Public Constructors
        /// <summary>
        /// Constructs an instance of this class using the specified iterator
        /// instance.
        /// </summary>
        /// <param name="iterator">
        /// The managed iterator instance to use.
        /// </param>
        public SQLiteChangeSetMetadataItem(
            SQLiteChangeSetIterator iterator
            )
        {
            this.iterator = iterator;
        }