System.Data.SQLite

Login
This project makes use of Eagle, provided by Mistachkin Systems.
Eagle: Secure Software Automation

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

Changes In Branch experimental Excluding Merge-Ins

This is equivalent to a diff from 6c0d692f73 to 53e8310fda

2014-10-08
18:49
Various minor performance enhancements to the SQLiteDataReader class. Pursuant to [e122d26e70]. check-in: e6cc5d000b user: mistachkin tags: trunk
00:09
Update SQLite core library to the latest trunk code. check-in: 3c2212a03d user: mistachkin tags: trunk
2014-10-07
17:52
More performance adjustments to the data reader class. Pursuant to [e122d26e70]. Closed-Leaf check-in: 53e8310fda user: mistachkin tags: experimental
2014-10-06
22:38
Merge updates from trunk. check-in: 5fb0f836bd user: mistachkin tags: experimental
2014-09-29
00:26
Update Eagle in externals to the beta 31 release. check-in: 6c0d692f73 user: mistachkin tags: trunk
2014-09-26
21:25
Fix typo in the setup package data file. check-in: db47ff46aa user: mistachkin tags: trunk

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

38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52







-
+







    /// <summary>
    /// The connection the command is associated with
    /// </summary>
    private SQLiteConnection _cnn;
    /// <summary>
    /// The version of the connection the command is associated with
    /// </summary>
    private long _version;
    private int _version;
    /// <summary>
    /// Indicates whether or not a DataReader is active on the command.
    /// </summary>
    private WeakReference _activeReader;
    /// <summary>
    /// The timeout for the command, kludged because SQLite doesn't support per-command timeout values
    /// </summary>

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

516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
516
517
518
519
520
521
522

523
524
525
526
527
528
529
530







-
+







    /// Non-zero if the built-in (i.e. framework provided) connection string
    /// parser should be used when opening the connection.
    /// </summary>
    private bool _parseViaFramework;

    internal bool _binaryGuid;

    internal long _version;
    internal int _version;

    private event SQLiteAuthorizerEventHandler _authorizerHandler;
    private event SQLiteUpdateEventHandler _updateHandler;
    private event SQLiteCommitHandler _commitHandler;
    private event SQLiteTraceEventHandler _traceHandler;
    private event EventHandler _rollbackHandler;

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

84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98







-
+







    /// An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified
    /// </summary>
    private SQLiteKeyReader _keyInfo;

    /// <summary>
    /// Matches the version of the connection.
    /// </summary>
    internal long _version;
    internal int _version;

    /// <summary>
    /// The "stub" (i.e. placeholder) base schema name to use when returning
    /// column schema information.  Matches the base schema name used by the
    /// associated connection.
    /// </summary>
    private string _baseSchemaName;
265
266
267
268
269
270
271


272

273
274
275
276
277
278
279
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281







+
+
-
+








      if (_command == null)
        throw new InvalidOperationException("DataReader has been closed");

      if (_version == 0)
        throw new SQLiteException("Execution was aborted by the user");

      SQLiteConnection connection = _command.Connection;

      if (_command.Connection.State != ConnectionState.Open || _command.Connection._version != _version)
      if (connection._version != _version || connection.State != ConnectionState.Open)
        throw new InvalidOperationException("Connection was closed, statement was terminated");
    }

    /// <summary>
    /// Throw an error if a row is not loaded
    /// </summary>
    private void CheckValidRow()
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
457
458
459
460
461
462
463
464
465


466
467
468


469
470
471


472
473
474
475
476
477
478
479
480
481


482
483
484


485
486
487


488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504


505
506
507


508
509
510


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
592
593
594
595
596
597
598
599
600


601
602
603


604
605
606


607
608
609
610
611
612
613
614
615
616


617
618
619


620
621
622
623
624
625
626
627
628
629









630
631
632
633
634
635
636
637
638
639


640
641
642


643
644
645


646
647
648
649
650
651
652
653
654
655


656
657
658


659
660
661


662
663
664
665
666
667
668
669
670
671


672
673
674


675
676
677


678
679
680
681
682
683
684
685
686
687

688
689
690


691
692

693
694
695
696
697
698
699
700
701
702

703

704
705
706
707
708
709
710
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
457
458


459
460
461


462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

480
481
482


483
484
485


486
487
488
489
490
491
492
493
494
495
496

497
498
499


500
501
502


503
504
505
506
507
508
509
510
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
592


593
594
595


596
597
598
599
600
601
602
603
604
605
606

607
608


609
610
611

612
613
614
615
616
617
618
619
620
621

622
623
624


625
626
627


628
629
630
631
632
633
634
635
636
637
638

639
640
641


642
643
644









645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662

663
664
665


666
667
668


669
670
671
672
673
674
675
676
677
678
679

680
681
682


683
684
685


686
687
688
689
690
691
692
693
694
695
696

697
698
699


700
701
702


703
704
705
706
707
708
709
710
711
712
713

714
715


716
717
718

719
720
721
722
723
724
725
726
727
728
729
730

731
732
733
734
735
736
737
738







+
+
+
+
+










-
+


+
+
+
+
+
+
+
+
+
















-
-
-
-
+

-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+

-
+









-
+
+

-
-
+
+

-
-
+
+









-
+
+

-
-
+
+

-
-
+
+
















-
+
+

-
-
+
+

-
-
+
+









-
+
+

-
-
+
+

-
-
+
+
















-
+
+

-
-
+
+

-
-
+
+









-
+
+

-
-
+
+

-
-
-
+
+
+









-
+
+

-
-
+
+

-
-
+
+









-
+
+

-
-
+
+

-
-
+
+









-
+
+

-
-
+
+

-
-
+
+









-
+

-
-
+
+

-
+









-
+
+

-
-
+
+

-
-
+
+









-
+
+

-
-
+
+

-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+









-
+
+

-
-
+
+

-
-
+
+









-
+
+

-
-
+
+

-
-
+
+









-
+
+

-
-
+
+

-
-
+
+









-
+

-
-
+
+

-
+










+
-
+







        {
            CheckDisposed();
            CheckClosed();

            return _stepCount;
        }
    }

    private int PrivateVisibleFieldCount
    {
        get { return _fieldCount; }
    }

    /// <summary>
    /// Returns the number of visible fields in the current resultset
    /// </summary>
    public override int VisibleFieldCount
    {
      get
      {
        CheckDisposed();
        CheckClosed();
        return _fieldCount;
        return PrivateVisibleFieldCount;
      }
    }

    /// <summary>
    /// This method is used to make sure the result set is open and a row is currently available.
    /// </summary>
    private void VerifyForGet()
    {
        CheckClosed();
        CheckValidRow();
    }

    /// <summary>
    /// SQLite is inherently un-typed.  All datatypes in SQLite are natively strings.  The definition of the columns of a table
    /// and the affinity of returned types are all we have to go on to type-restrict data in the reader.
    ///
    /// This function attempts to verify that the type of data being requested of a column matches the datatype of the column.  In
    /// the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob)
    /// to a set of known types that closely match that affinity.  It's not an exact science, but its the best we can do.
    /// </summary>
    /// <returns>
    /// This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity.
    /// </returns>
    /// <param name="i">The index of the column to type-check</param>
    /// <param name="typ">The type we want to get out of the column</param>
    private TypeAffinity VerifyType(int i, DbType typ)
    {
      CheckClosed();
      CheckValidRow();

      TypeAffinity affinity = GetSQLiteType(_flags, i).Affinity;
        TypeAffinity affinity = GetSQLiteType(_flags, i).Affinity;

      switch (affinity)
      {
        case TypeAffinity.Int64:
          if (typ == DbType.Int16) return affinity;
          if (typ == DbType.Int32) return affinity;
          if (typ == DbType.Int64) return affinity;
          if (typ == DbType.Boolean) return affinity;
          if (typ == DbType.SByte) return affinity;
          if (typ == DbType.Byte) return affinity;
          if (typ == DbType.DateTime) return affinity;
        switch (affinity)
        {
            case TypeAffinity.Int64:
                if (typ == DbType.Int64) return affinity;
                if (typ == DbType.Int32) return affinity;
                if (typ == DbType.Int16) return affinity;
                if (typ == DbType.Byte) return affinity;
                if (typ == DbType.SByte) return affinity;
                if (typ == DbType.Boolean) return affinity;
                if (typ == DbType.DateTime) return affinity;
          if (typ == DbType.Single) return affinity;
          if (typ == DbType.Double) return affinity;
          if (typ == DbType.Decimal) return affinity;
          break;
        case TypeAffinity.Double:
                if (typ == DbType.Double) return affinity;
                if (typ == DbType.Single) return affinity;
                if (typ == DbType.Decimal) return affinity;
                break;
            case TypeAffinity.Double:
          if (typ == DbType.Single) return affinity;
          if (typ == DbType.Double) return affinity;
          if (typ == DbType.Decimal) return affinity;
          if (typ == DbType.DateTime) return affinity;
          break;
        case TypeAffinity.Text:
          if (typ == DbType.String) return affinity;
          if (typ == DbType.Guid) return affinity;
          if (typ == DbType.DateTime) return affinity;
          if (typ == DbType.Decimal) return affinity;
          break;
        case TypeAffinity.Blob:
          if (typ == DbType.Guid) return affinity;
                if (typ == DbType.Double) return affinity;
                if (typ == DbType.Single) return affinity;
                if (typ == DbType.Decimal) return affinity;
                if (typ == DbType.DateTime) return affinity;
                break;
            case TypeAffinity.Text:
                if (typ == DbType.String) return affinity;
                if (typ == DbType.Guid) return affinity;
                if (typ == DbType.DateTime) return affinity;
                if (typ == DbType.Decimal) return affinity;
                break;
            case TypeAffinity.Blob:
                if (typ == DbType.Guid) return affinity;
          if (typ == DbType.String) return affinity;
          if (typ == DbType.Binary) return affinity;
          break;
      }
                if (typ == DbType.Binary) return affinity;
                if (typ == DbType.String) return affinity;
                break;
        }

      throw new InvalidCastException();
        throw new InvalidCastException();
    }

    /// <summary>
    /// Retrieves the column as a boolean value
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>bool</returns>
    public override bool GetBoolean(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetBoolean(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetBoolean(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.Boolean);
      return Convert.ToBoolean(GetValue(i), CultureInfo.CurrentCulture);
        VerifyType(i, DbType.Boolean);
        return Convert.ToBoolean(GetValue(i), CultureInfo.CurrentCulture);
    }

    /// <summary>
    /// Retrieves the column as a single byte value
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>byte</returns>
    public override byte GetByte(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetByte(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetByte(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.Byte);
      return Convert.ToByte(_activeStatement._sql.GetInt32(_activeStatement, i));
        VerifyType(i, DbType.Byte);
        return Convert.ToByte(_activeStatement._sql.GetInt32(_activeStatement, i));
    }

    /// <summary>
    /// Retrieves a column as an array of bytes (blob)
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <param name="fieldOffset">The zero-based index of where to begin reading the data</param>
    /// <param name="buffer">The buffer to write the bytes into</param>
    /// <param name="bufferoffset">The zero-based index of where to begin writing into the array</param>
    /// <param name="length">The number of bytes to retrieve</param>
    /// <returns>The actual number of bytes written into the array</returns>
    /// <remarks>
    /// To determine the number of bytes in the column, pass a null value for the buffer.  The total length will be returned.
    /// </remarks>
    public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetBytes(i - VisibleFieldCount, fieldOffset, buffer, bufferoffset, length);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetBytes(i - PrivateVisibleFieldCount, fieldOffset, buffer, bufferoffset, length);

      VerifyType(i, DbType.Binary);
      return _activeStatement._sql.GetBytes(_activeStatement, i, (int)fieldOffset, buffer, bufferoffset, length);
        VerifyType(i, DbType.Binary);
        return _activeStatement._sql.GetBytes(_activeStatement, i, (int)fieldOffset, buffer, bufferoffset, length);
    }

    /// <summary>
    /// Returns the column as a single character
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>char</returns>
    public override char GetChar(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetChar(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetChar(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.SByte);
      return Convert.ToChar(_activeStatement._sql.GetInt32(_activeStatement, i));
        VerifyType(i, DbType.SByte);
        return Convert.ToChar(_activeStatement._sql.GetInt32(_activeStatement, i));
    }

    /// <summary>
    /// Retrieves a column as an array of chars (blob)
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <param name="fieldoffset">The zero-based index of where to begin reading the data</param>
    /// <param name="buffer">The buffer to write the characters into</param>
    /// <param name="bufferoffset">The zero-based index of where to begin writing into the array</param>
    /// <param name="length">The number of bytes to retrieve</param>
    /// <returns>The actual number of characters written into the array</returns>
    /// <remarks>
    /// To determine the number of characters in the column, pass a null value for the buffer.  The total length will be returned.
    /// </remarks>
    public override long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetChars(i - VisibleFieldCount, fieldoffset, buffer, bufferoffset, length);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetChars(i - PrivateVisibleFieldCount, fieldoffset, buffer, bufferoffset, length);

      VerifyType(i, DbType.String);
      return _activeStatement._sql.GetChars(_activeStatement, i, (int)fieldoffset, buffer, bufferoffset, length);
        VerifyType(i, DbType.String);
        return _activeStatement._sql.GetChars(_activeStatement, i, (int)fieldoffset, buffer, bufferoffset, length);
    }

    /// <summary>
    /// Retrieves the name of the back-end datatype of the column
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>string</returns>
    public override string GetDataTypeName(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetDataTypeName(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetDataTypeName(i - PrivateVisibleFieldCount);

      SQLiteType typ = GetSQLiteType(_flags, i);
      if (typ.Type == DbType.Object) return SQLiteConvert.SQLiteTypeToType(typ).Name;
      return _activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity);
        SQLiteType typ = GetSQLiteType(_flags, i);
        if (typ.Type == DbType.Object) return SQLiteConvert.SQLiteTypeToType(typ).Name;
        return _activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity);
    }

    /// <summary>
    /// Retrieve the column as a date/time value
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>DateTime</returns>
    public override DateTime GetDateTime(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetDateTime(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetDateTime(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.DateTime);
      return _activeStatement._sql.GetDateTime(_activeStatement, i);
        VerifyType(i, DbType.DateTime);
        return _activeStatement._sql.GetDateTime(_activeStatement, i);
    }

    /// <summary>
    /// Retrieve the column as a decimal value
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>decimal</returns>
    public override decimal GetDecimal(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetDecimal(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetDecimal(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.Decimal);
      return Decimal.Parse(_activeStatement._sql.GetText(_activeStatement, i), NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent | NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture);
        VerifyType(i, DbType.Decimal);
        return Decimal.Parse(_activeStatement._sql.GetText(_activeStatement, i), NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent | NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture);
    }

    /// <summary>
    /// Returns the column as a double
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>double</returns>
    public override double GetDouble(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetDouble(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetDouble(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.Double);
      return _activeStatement._sql.GetDouble(_activeStatement, i);
        VerifyType(i, DbType.Double);
        return _activeStatement._sql.GetDouble(_activeStatement, i);
    }

    /// <summary>
    /// Returns the .NET type of a given column
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>Type</returns>
    public override Type GetFieldType(int i)
    {
      CheckDisposed();
        CheckDisposed();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetFieldType(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetFieldType(i - PrivateVisibleFieldCount);

      return SQLiteConvert.SQLiteTypeToType(GetSQLiteType(_flags, i));
        return SQLiteConvert.SQLiteTypeToType(GetSQLiteType(_flags, i));
    }

    /// <summary>
    /// Returns a column as a float value
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>float</returns>
    public override float GetFloat(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetFloat(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetFloat(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.Single);
      return Convert.ToSingle(_activeStatement._sql.GetDouble(_activeStatement, i));
        VerifyType(i, DbType.Single);
        return Convert.ToSingle(_activeStatement._sql.GetDouble(_activeStatement, i));
    }

    /// <summary>
    /// Returns the column as a Guid
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>Guid</returns>
    public override Guid GetGuid(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetGuid(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetGuid(i - PrivateVisibleFieldCount);

      TypeAffinity affinity = VerifyType(i, DbType.Guid);
      if (affinity == TypeAffinity.Blob)
      {
        byte[] buffer = new byte[16];
        _activeStatement._sql.GetBytes(_activeStatement, i, 0, buffer, 0, 16);
        return new Guid(buffer);
      }
      else
        return new Guid(_activeStatement._sql.GetText(_activeStatement, i));
        TypeAffinity affinity = VerifyType(i, DbType.Guid);
        if (affinity == TypeAffinity.Blob)
        {
            byte[] buffer = new byte[16];
            _activeStatement._sql.GetBytes(_activeStatement, i, 0, buffer, 0, 16);
            return new Guid(buffer);
        }
        else
            return new Guid(_activeStatement._sql.GetText(_activeStatement, i));
    }

    /// <summary>
    /// Returns the column as a short
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>Int16</returns>
    public override Int16 GetInt16(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetInt16(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetInt16(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.Int16);
      return Convert.ToInt16(_activeStatement._sql.GetInt32(_activeStatement, i));
        VerifyType(i, DbType.Int16);
        return Convert.ToInt16(_activeStatement._sql.GetInt32(_activeStatement, i));
    }

    /// <summary>
    /// Retrieves the column as an int
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>Int32</returns>
    public override Int32 GetInt32(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetInt32(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetInt32(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.Int32);
      return _activeStatement._sql.GetInt32(_activeStatement, i);
        VerifyType(i, DbType.Int32);
        return _activeStatement._sql.GetInt32(_activeStatement, i);
    }

    /// <summary>
    /// Retrieves the column as a long
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>Int64</returns>
    public override Int64 GetInt64(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetInt64(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetInt64(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.Int64);
      return _activeStatement._sql.GetInt64(_activeStatement, i);
        VerifyType(i, DbType.Int64);
        return _activeStatement._sql.GetInt64(_activeStatement, i);
    }

    /// <summary>
    /// Retrieves the name of the column
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>string</returns>
    public override string GetName(int i)
    {
      CheckDisposed();
        CheckDisposed();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetName(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetName(i - PrivateVisibleFieldCount);

      return _activeStatement._sql.ColumnName(_activeStatement, i);
        return _activeStatement._sql.ColumnName(_activeStatement, i);
    }

    /// <summary>
    /// Retrieves the i of a column, given its name
    /// </summary>
    /// <param name="name">The name of the column to retrieve</param>
    /// <returns>The int i of the column</returns>
    public override int GetOrdinal(string name)
    {
      CheckDisposed();
      VerifyForGet();
      CheckClosed();

      if (_throwOnDisposed) SQLiteCommand.Check(_command);

      //
      // NOTE: First, check if the column name cache has been initialized yet.
      //       If not, do it now.
      //
      if (_fieldIndexes == null)
723
724
725
726
727
728
729
730

731
732
733
734
735
736
737
751
752
753
754
755
756
757

758
759
760
761
762
763
764
765







-
+







      if (!_fieldIndexes.TryGetValue(name, out r))
      {
          r = _activeStatement._sql.ColumnIndex(_activeStatement, name);

          if (r == -1 && _keyInfo != null)
          {
              r = _keyInfo.GetOrdinal(name);
              if (r > -1) r += VisibleFieldCount;
              if (r > -1) r += PrivateVisibleFieldCount;
          }

          _fieldIndexes.Add(name, r);
      }

      return r;
    }
1121
1122
1123
1124
1125
1126
1127
1128


1129
1130
1131


1132
1133
1134


1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145


1146
1147
1148


1149
1150

1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163












1164
1165

1166
1167
1168
1169
1170
1171
1172
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158


1159
1160
1161


1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172


1173
1174
1175


1176
1177
1178

1179
1180












1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193

1194
1195
1196
1197
1198
1199
1200
1201







-
+
+

-
-
+
+

-
-
+
+









-
-
+
+

-
-
+
+

-
+

-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+

-
+







    /// <summary>
    /// Retrieves the column as a string
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>string</returns>
    public override string GetString(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetString(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetString(i - PrivateVisibleFieldCount);

      VerifyType(i, DbType.String);
      return _activeStatement._sql.GetText(_activeStatement, i);
        VerifyType(i, DbType.String);
        return _activeStatement._sql.GetText(_activeStatement, i);
    }

    /// <summary>
    /// Retrieves the column as an object corresponding to the underlying datatype of the column
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>object</returns>
    public override object GetValue(int i)
    {
      CheckDisposed();
      CheckValidRow();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.GetValue(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.GetValue(i - PrivateVisibleFieldCount);

      SQLiteType typ = GetSQLiteType(_flags, i);
        SQLiteType typ = GetSQLiteType(_flags, i);

      if (((_flags & SQLiteConnectionFlags.DetectTextAffinity) == SQLiteConnectionFlags.DetectTextAffinity) &&
          ((typ == null) || (typ.Affinity == TypeAffinity.Text)))
      {
          typ = GetSQLiteType(
              typ, _activeStatement._sql.GetText(_activeStatement, i));
      }
      else if (((_flags & SQLiteConnectionFlags.DetectStringType) == SQLiteConnectionFlags.DetectStringType) &&
          ((typ == null) || SQLiteConvert.IsStringDbType(typ.Type)))
      {
          typ = GetSQLiteType(
              typ, _activeStatement._sql.GetText(_activeStatement, i));
      }
        if (((_flags & SQLiteConnectionFlags.DetectTextAffinity) == SQLiteConnectionFlags.DetectTextAffinity) &&
            ((typ == null) || (typ.Affinity == TypeAffinity.Text)))
        {
            typ = GetSQLiteType(
                typ, _activeStatement._sql.GetText(_activeStatement, i));
        }
        else if (((_flags & SQLiteConnectionFlags.DetectStringType) == SQLiteConnectionFlags.DetectStringType) &&
            ((typ == null) || SQLiteConvert.IsStringDbType(typ.Type)))
        {
            typ = GetSQLiteType(
                typ, _activeStatement._sql.GetText(_activeStatement, i));
        }

      return _activeStatement._sql.GetValue(_activeStatement, _flags, i, typ);
        return _activeStatement._sql.GetValue(_activeStatement, _flags, i, typ);
    }

    /// <summary>
    /// Retreives the values of multiple columns, up to the size of the supplied array
    /// </summary>
    /// <param name="values">The array to fill with values from the columns in the current resultset</param>
    /// <returns>The number of columns retrieved</returns>
1198
1199
1200
1201
1202
1203
1204
1205

1206
1207
1208
1209
1210
1211
1212
1227
1228
1229
1230
1231
1232
1233

1234
1235
1236
1237
1238
1239
1240
1241







-
+







    public NameValueCollection GetValues()
    {
        CheckDisposed();

        if ((_activeStatement == null) || (_activeStatement._sql == null))
            throw new InvalidOperationException();

        int nMax = VisibleFieldCount;
        int nMax = PrivateVisibleFieldCount;
        NameValueCollection result = new NameValueCollection(nMax);

        for (int n = 0; n < nMax; n++)
        {
            string name = _activeStatement._sql.ColumnName(_activeStatement, n);
            string value = _activeStatement._sql.GetText(_activeStatement, n);

1258
1259
1260
1261
1262
1263
1264
1265


1266
1267
1268


1269
1270

1271
1272
1273
1274
1275
1276
1277
1287
1288
1289
1290
1291
1292
1293

1294
1295
1296


1297
1298
1299

1300
1301
1302
1303
1304
1305
1306
1307







-
+
+

-
-
+
+

-
+







    /// <summary>
    /// Returns True if the specified column is null
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>True or False</returns>
    public override bool IsDBNull(int i)
    {
      CheckDisposed();
        CheckDisposed();
        VerifyForGet();

      if (i >= VisibleFieldCount && _keyInfo != null)
        return _keyInfo.IsDBNull(i - VisibleFieldCount);
        if (i >= PrivateVisibleFieldCount && _keyInfo != null)
            return _keyInfo.IsDBNull(i - PrivateVisibleFieldCount);

      return _activeStatement._sql.IsNull(_activeStatement, i);
        return _activeStatement._sql.IsNull(_activeStatement, i);
    }

    /// <summary>
    /// Moves to the next resultset in multiple row-returning SQL command.
    /// </summary>
    /// <returns>True if the command was successful and a new resultset is available, False otherwise.</returns>
    public override bool NextResult()
1356
1357
1358
1359
1360
1361
1362
1363
1364


1365
1366
1367
1368
1369
1370
1371
1386
1387
1388
1389
1390
1391
1392


1393
1394
1395
1396
1397
1398
1399
1400
1401







-
-
+
+







            _readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false
          }
        }

        // Ahh, we found a row-returning resultset eligible to be returned!
        _activeStatement = stmt;
        _fieldCount = fieldCount;
        _fieldIndexes = null;
        _fieldTypeArray = null;
        _fieldIndexes = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
        _fieldTypeArray = new SQLiteType[PrivateVisibleFieldCount];

        if ((_commandBehavior & CommandBehavior.KeyInfo) != 0)
          LoadKeyInfo();

        return true;
      }
    }
1444
1445
1446
1447
1448
1449
1450
1451

1452
1453
1454

1455
1456
1457
1458
1459




1460
1461
1462
1463
1464
1465
1466
1467
1468
1469















1470
1471
1472
1473
1474
1475
1476
1474
1475
1476
1477
1478
1479
1480

1481
1482


1483





1484
1485
1486
1487

1488








1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510







-
+

-
-
+
-
-
-
-
-
+
+
+
+
-

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    /// Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls.
    /// </summary>
    /// <param name="flags">The flags associated with the parent connection object.</param>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>A SQLiteType structure</returns>
    private SQLiteType GetSQLiteType(SQLiteConnectionFlags flags, int i)
    {
      SQLiteType typ;
        SQLiteType typ = _fieldTypeArray[i];

      // Initialize the field types array if not already initialized
      if (_fieldTypeArray == null)
        if (typ == null)
        _fieldTypeArray = new SQLiteType[VisibleFieldCount];

      // Initialize this column's field type instance
      if (_fieldTypeArray[i] == null) _fieldTypeArray[i] = new SQLiteType();

        {
            // Initialize this column's field type instance
            typ = _fieldTypeArray[i] = new SQLiteType();
        }
      typ = _fieldTypeArray[i];

      // If not initialized, then fetch the declared column datatype and attempt to convert it
      // to a known DbType.
      if (typ.Affinity == TypeAffinity.Uninitialized)
        typ.Type = SQLiteConvert.TypeNameToDbType(GetConnection(this), _activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity), flags);
      else
        typ.Affinity = _activeStatement._sql.ColumnAffinity(_activeStatement, i);

      return typ;
        // If not initialized, then fetch the declared column datatype and attempt to convert it
        // to a known DbType.
        if (typ.Affinity == TypeAffinity.Uninitialized)
        {
            typ.Type = SQLiteConvert.TypeNameToDbType(
                GetConnection(this), _activeStatement._sql.ColumnType(
                _activeStatement, i, out typ.Affinity), flags);
        }
        else
        {
            typ.Affinity = _activeStatement._sql.ColumnAffinity(
                _activeStatement, i);
        }

        return typ;
    }

    /// <summary>
    /// Reads the next row from the resultset
    /// </summary>
    /// <returns>True if a new row was successfully loaded and is ready for processing</returns>
    public override bool Read()

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

17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31







-
+







  /// </summary>
  public sealed class SQLiteTransaction : DbTransaction
  {
    /// <summary>
    /// The connection to which this transaction is bound
    /// </summary>
    internal SQLiteConnection _cnn;
    internal long _version; // Matches the version of the connection
    internal int _version; // Matches the version of the connection
    private IsolationLevel _level;

    /// <summary>
    /// Constructs the transaction object, binding it to the supplied connection
    /// </summary>
    /// <param name="connection">The connection to open a transaction on</param>
    /// <param name="deferredLock">TRUE to defer the writelock, or FALSE to lock immediately</param>