System.Data.SQLite

Check-in [740d7652e8]
Login

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

Overview
Comment:Add the 'TextHexPassword' connection string property.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 740d7652e8301dc15e821a2da7e6e850e1c75a8c
User & Date: mistachkin 2023-04-01 04:23:23.957
Context
2023-04-08
20:11
Update SQLite core library to the latest 3.41 release branch code. check-in: 2517335da5 user: mistachkin tags: trunk
2023-04-01
04:23
Add the 'TextHexPassword' connection string property. check-in: 740d7652e8 user: mistachkin tags: trunk
2023-03-01
22:41
Attempt to disable Microsoft telemetry at build time. check-in: 6b7664f039 user: mistachkin tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to Doc/Extra/Provider/version.html.
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
    <h1 class="heading">Version History</h1>
    <p><b>1.0.118.0 - March XX, 2023 <font color="red">(release scheduled)</font></b></p>
    <ul>
      <li>Add the ConnectionStringPreview, SqlStringPreview, and Canceled connection events.</li>
      <li>Add support for the sqlite3_is_interrupted core library API. Pursuant to forum post <a href="https://www.sqlite.org/forum/forumpost/b6a707bffb">[b6a707bffb]</a>.</li>
      <li>Add support for the sqlite_trace_v2 core library API. Pursuant to forum post <a href="https://www.sqlite.org/forum/forumpost/1c418d7edc">[1c418d7edc]</a>.</li>

    </ul>
    <p><b>1.0.117.0 - November 28, 2022</b></p>
    <ul>
      <li>Updated to <a href="https://www.sqlite.org/releaselog/3_40_0.html">SQLite 3.40.0</a>.</li>
      <li>Add support for creating custom window functions. Pursuant to forum post <a href="https://www.sqlite.org/forum/forumpost/21de219031">[21de219031]</a>.</li>
      <li>Suppress finalizer calls for SQLite3 objects that are closed. Fix for <a href="https://system.data.sqlite.org/index.html/info/ce4d70ea6f">[ce4d70ea6f]</a>.</li>
      <li>Improvements to object disposal diagnostics. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/ce4d70ea6f">[ce4d70ea6f]</a>.</li>







|




>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
    <h1 class="heading">Version History</h1>
    <p><b>1.0.118.0 - April XX, 2023 <font color="red">(release scheduled)</font></b></p>
    <ul>
      <li>Add the ConnectionStringPreview, SqlStringPreview, and Canceled connection events.</li>
      <li>Add support for the sqlite3_is_interrupted core library API. Pursuant to forum post <a href="https://www.sqlite.org/forum/forumpost/b6a707bffb">[b6a707bffb]</a>.</li>
      <li>Add support for the sqlite_trace_v2 core library API. Pursuant to forum post <a href="https://www.sqlite.org/forum/forumpost/1c418d7edc">[1c418d7edc]</a>.</li>
      <li>Add TextHexPassword connection string property for use with <a href="https://www.sqlite.org/see">SEE</a>.</li>
    </ul>
    <p><b>1.0.117.0 - November 28, 2022</b></p>
    <ul>
      <li>Updated to <a href="https://www.sqlite.org/releaselog/3_40_0.html">SQLite 3.40.0</a>.</li>
      <li>Add support for creating custom window functions. Pursuant to forum post <a href="https://www.sqlite.org/forum/forumpost/21de219031">[21de219031]</a>.</li>
      <li>Suppress finalizer calls for SQLite3 objects that are closed. Fix for <a href="https://system.data.sqlite.org/index.html/info/ce4d70ea6f">[ce4d70ea6f]</a>.</li>
      <li>Improvements to object disposal diagnostics. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/ce4d70ea6f">[ce4d70ea6f]</a>.</li>
Changes to System.Data.SQLite/SQLiteConnection.cs.
1196
1197
1198
1199
1200
1201
1202













1203
1204
1205
1206
1207
1208
1209
  /// both the native interop assembly and the core managed assemblies; otherwise,
  /// using this parameter may result in an exception being thrown when attempting
  /// to open the connection.
  /// </description>
  /// <description>N</description>
  /// <description></description>
  /// </item>













  /// <item>
  /// <description>Enlist</description>
  /// <description>
  /// <b>Y</b> - Automatically enlist in distributed transactions
  /// <br/>
  /// <b>N</b> - No automatic enlistment
  /// </description>







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







1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
  /// both the native interop assembly and the core managed assemblies; otherwise,
  /// using this parameter may result in an exception being thrown when attempting
  /// to open the connection.
  /// </description>
  /// <description>N</description>
  /// <description></description>
  /// </item>
  /// <item>
  /// <description>TextHexPassword</description>
  /// <description>
  /// {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded
  /// byte values without a leading "0x" prefix.  Using this parameter requires
  /// that the legacy CryptoAPI based codec (or the SQLite Encryption Extension)
  /// be enabled at compile-time for both the native interop assembly and the
  /// core managed assemblies; otherwise, using this parameter may result in an
  /// exception being thrown when attempting to open the connection.
  /// </description>
  /// <description>N</description>
  /// <description></description>
  /// </item>
  /// <item>
  /// <description>Enlist</description>
  /// <description>
  /// <b>Y</b> - Automatically enlist in distributed transactions
  /// <br/>
  /// <b>N</b> - No automatic enlistment
  /// </description>
1418
1419
1420
1421
1422
1423
1424

1425
1426
1427
1428
1429
1430
1431
    internal const SQLiteDateFormats DefaultDateTimeFormat = SQLiteDateFormats.Default;
    internal const DateTimeKind DefaultDateTimeKind = DateTimeKind.Unspecified;
    internal const string DefaultDateTimeFormatString = null;
    private const string DefaultDataSource = null;
    private const string DefaultUri = null;
    private const string DefaultFullUri = null;
    private const string DefaultTextPassword = null;

    private const string DefaultHexPassword = null;
    private const string DefaultPassword = null;
    private const int DefaultVersion = 3;
    private const int DefaultPageSize = 4096;
    private const int DefaultMaxPageCount = 0;
    private const int DefaultCacheSize = -2000;
    private const int DefaultMaxPoolSize = 100;







>







1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
    internal const SQLiteDateFormats DefaultDateTimeFormat = SQLiteDateFormats.Default;
    internal const DateTimeKind DefaultDateTimeKind = DateTimeKind.Unspecified;
    internal const string DefaultDateTimeFormatString = null;
    private const string DefaultDataSource = null;
    private const string DefaultUri = null;
    private const string DefaultFullUri = null;
    private const string DefaultTextPassword = null;
    private const string DefaultTextHexPassword = null;
    private const string DefaultHexPassword = null;
    private const string DefaultPassword = null;
    private const int DefaultVersion = 3;
    private const int DefaultPageSize = 4096;
    private const int DefaultMaxPageCount = 0;
    private const int DefaultCacheSize = -2000;
    private const int DefaultMaxPoolSize = 100;
1601
1602
1603
1604
1605
1606
1607
1608

1609
1610
1611
1612
1613
1614
1615
1616
1617
#if INTEROP_CODEC || INTEROP_INCLUDE_SEE
    /// <summary>
    /// Temporary password storage, emptied after the database has been opened
    /// </summary>
    private byte[] _password;

    /// <summary>
    /// This will be non-zero if the "TextPassword" connection string property

    /// was used.  When this value is non-zero, <see cref="ChangePassword(Byte[])" />
    /// will retain treatment of the password as a NUL-terminated text string.
    /// </summary>
    private bool _passwordWasText;
#endif

    /// <summary>
    /// The "stub" (i.e. placeholder) base schema name to use when returning
    /// column schema information.







|
>
|
|







1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
#if INTEROP_CODEC || INTEROP_INCLUDE_SEE
    /// <summary>
    /// Temporary password storage, emptied after the database has been opened
    /// </summary>
    private byte[] _password;

    /// <summary>
    /// This will be non-zero if the "TextPassword" or "TextHexPassword"
    /// connection string properties were used.  When this value is non-zero,
    /// <see cref="ChangePassword(Byte[])" /> will retain treatment of the
    /// password as a NUL-terminated text string.
    /// </summary>
    private bool _passwordWasText;
#endif

    /// <summary>
    /// The "stub" (i.e. placeholder) base schema name to use when returning
    /// column schema information.
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
    /// </returns>
    internal static byte[] FromHexString(
        string text
        )
    {
        string error = null;

        return FromHexString(text, ref error);
    }

    /// <summary>
    /// Creates and returns a string containing the hexadecimal encoded byte
    /// values from the input array.
    /// </summary>
    /// <param name="array">







|







4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
    /// </returns>
    internal static byte[] FromHexString(
        string text
        )
    {
        string error = null;

        return FromHexString(text, true, ref error);
    }

    /// <summary>
    /// Creates and returns a string containing the hexadecimal encoded byte
    /// values from the input array.
    /// </summary>
    /// <param name="array">
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
4436
4437
4438
4439
4440



4441
4442
4443
4444
4445
4446
4447
    /// encoded byte values and returns the resulting byte array.  The
    /// "0x" prefix is not allowed on the input string.
    /// </summary>
    /// <param name="text">
    /// The input string containing zero or more hexadecimal encoded byte
    /// values.
    /// </param>




    /// <param name="error">
    /// Upon failure, this will contain an appropriate error message.
    /// </param>
    /// <returns>
    /// A byte array containing the parsed byte values or null if an error
    /// was encountered.
    /// </returns>
    private static byte[] FromHexString(
        string text,

        ref string error
        )
    {
        if (text == null)
        {
            error = "string is null";
            return null;
        }

        if (text.Length % 2 != 0)
        {
            error = "string contains an odd number of characters";
            return null;
        }

        byte[] result = new byte[text.Length / 2];

        for (int index = 0; index < text.Length; index += 2)
        {
            string value = text.Substring(index, 2);


            if (!TryParseByte(value,
                    NumberStyles.HexNumber, out result[index / 2]))
            {
                error = HelperMethods.StringFormat(
                    CultureInfo.CurrentCulture,
                    "string contains \"{0}\", which cannot be converted to a byte value",
                    value);

                return null;
            }



        }

        return result;
    }

    /// <summary>
    /// This method figures out what the default connection pool setting should







>
>
>
>









>




















>


|








>
>
>







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
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
    /// encoded byte values and returns the resulting byte array.  The
    /// "0x" prefix is not allowed on the input string.
    /// </summary>
    /// <param name="text">
    /// The input string containing zero or more hexadecimal encoded byte
    /// values.
    /// </param>
    /// <param name="allowNul">
    /// When zero, byte values of zero are not allowed and will be changed
    /// to <see cref="Byte.MaxValue" /> instead.
    /// </param>
    /// <param name="error">
    /// Upon failure, this will contain an appropriate error message.
    /// </param>
    /// <returns>
    /// A byte array containing the parsed byte values or null if an error
    /// was encountered.
    /// </returns>
    private static byte[] FromHexString(
        string text,
        bool allowNul,
        ref string error
        )
    {
        if (text == null)
        {
            error = "string is null";
            return null;
        }

        if (text.Length % 2 != 0)
        {
            error = "string contains an odd number of characters";
            return null;
        }

        byte[] result = new byte[text.Length / 2];

        for (int index = 0; index < text.Length; index += 2)
        {
            string value = text.Substring(index, 2);
            int outIndex = index / 2;

            if (!TryParseByte(value,
                    NumberStyles.HexNumber, out result[outIndex]))
            {
                error = HelperMethods.StringFormat(
                    CultureInfo.CurrentCulture,
                    "string contains \"{0}\", which cannot be converted to a byte value",
                    value);

                return null;
            }

            if (!allowNul && (result[outIndex] == 0))
                result[outIndex] = byte.MaxValue;
        }

        return result;
    }

    /// <summary>
    /// This method figures out what the default connection pool setting should
4605
4606
4607
4608
4609
4610
4611







4612
4613
4614
4615
4616
4617
4618
                  continue;
              }

              if (String.Equals(
                    pair.Key, "TextPassword",
                    StringComparison.OrdinalIgnoreCase))
              {







                  continue;
              }

              eventArgOpts.Add(pair.Key, pair.Value);
          }

          eventArgConnectionString = BuildConnectionString(







>
>
>
>
>
>
>







4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
                  continue;
              }

              if (String.Equals(
                    pair.Key, "TextPassword",
                    StringComparison.OrdinalIgnoreCase))
              {
                  continue;
              }

              if (String.Equals(
                    pair.Key, "TextHexPassword",
                    StringComparison.OrdinalIgnoreCase))
              {
                  continue;
              }

              eventArgOpts.Add(pair.Key, pair.Value);
          }

          eventArgConnectionString = BuildConnectionString(
4829
4830
4831
4832
4833
4834
4835

4836
4837
4838
4839

4840


4841

4842





4843

4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869






















4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888

4889
4890
4891
4892
4893
4894
4895



4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907








4908
4909
4910
4911
4912
4913
4914

        stringValue = FindKey(opts, "BinaryGUID", null);

        if (stringValue != null)
            _binaryGuid = SQLiteConvert.ToBoolean(stringValue);

#if INTEROP_CODEC || INTEROP_INCLUDE_SEE

        string textPassword = FindKey(opts, "TextPassword", DefaultTextPassword);

        if (textPassword != null)
        {

            byte[] textPasswordBytes = UTF8Encoding.UTF8.GetBytes(


                textPassword); /* throw */







            Array.Resize(ref textPasswordBytes, textPasswordBytes.Length + 1);


            _sql.SetPassword(textPasswordBytes, true);
            _passwordWasText = true;
        }
        else
        {
            string hexPassword = FindKey(opts, "HexPassword", DefaultHexPassword);

            if (hexPassword != null)
            {
                string error = null;
                byte[] hexPasswordBytes = FromHexString(hexPassword, ref error);

                if (hexPasswordBytes == null)
                {
                    throw new FormatException(HelperMethods.StringFormat(
                        CultureInfo.CurrentCulture,
                        "Cannot parse 'HexPassword' property value into byte values: {0}",
                        error));
                }

                _sql.SetPassword(hexPasswordBytes, false);
                _passwordWasText = false;
            }
            else
            {






















                string password = FindKey(opts, "Password", DefaultPassword);

                if (password != null)
                {
                    byte[] passwordBytes = UTF8Encoding.UTF8.GetBytes(
                        password); /* throw */

                    _sql.SetPassword(passwordBytes, false);
                    _passwordWasText = false;
                }
                else if (_password != null)
                {
                    _sql.SetPassword(_password, _passwordWasText);
                }

                password = null; /* IMMUTABLE */
            }

            hexPassword = null; /* IMMUTABLE */

        }

        textPassword = null; /* IMMUTABLE */
        _password = null; /* IMMUTABLE */

        if (hidePassword)
        {



            if (opts.ContainsKey("TextPassword"))
                opts["TextPassword"] = String.Empty;

            if (opts.ContainsKey("HexPassword"))
                opts["HexPassword"] = String.Empty;

            if (opts.ContainsKey("Password"))
                opts["Password"] = String.Empty;

            _connectionString = BuildConnectionString(opts);
        }
#else








        if (FindKey(opts, "TextPassword", null) != null)
        {
            throw new SQLiteException(SQLiteErrorCode.Error,
                "Cannot use \"TextPassword\" connection string property: " +
                "library was not built with encryption support, please " +
                "see \"https://www.sqlite.org/see\" for more information");
        }







>
|

|

>
|
>
>
|
>
|
>
>
>
>
>
|
>

|




|

|

<
<
|
|
|
<
<
|
<
|
<
|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|
|
|
|

|
|
|
|
|
|
|

|
|

|
>







>
>
>












>
>
>
>
>
>
>
>







4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895


4896
4897
4898


4899

4900

4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984

        stringValue = FindKey(opts, "BinaryGUID", null);

        if (stringValue != null)
            _binaryGuid = SQLiteConvert.ToBoolean(stringValue);

#if INTEROP_CODEC || INTEROP_INCLUDE_SEE
        string error; /* REUSED */
        string textHexPassword = FindKey(opts, "TextHexPassword", DefaultTextHexPassword);

        if (textHexPassword != null)
        {
            byte[] textHexPasswordBytes;

            error = null;
            textHexPasswordBytes = FromHexString(textHexPassword, false, ref error);

            if (textHexPasswordBytes == null)
            {
                throw new FormatException(HelperMethods.StringFormat(
                    CultureInfo.CurrentCulture,
                    "Cannot parse 'TextHexPassword' property value into byte values: {0}",
                    error));
            }

            Array.Resize(ref textHexPasswordBytes, textHexPasswordBytes.Length + 1);

            _sql.SetPassword(textHexPasswordBytes, true);
            _passwordWasText = true;
        }
        else
        {
            string textPassword = FindKey(opts, "TextPassword", DefaultTextPassword);

            if (textPassword != null)
            {


                byte[] textPasswordBytes = UTF8Encoding.UTF8.GetBytes(
                    textPassword); /* throw */



                Array.Resize(ref textPasswordBytes, textPasswordBytes.Length + 1);



                _sql.SetPassword(textPasswordBytes, true);
                _passwordWasText = true;
            }
            else
            {
                string hexPassword = FindKey(opts, "HexPassword", DefaultHexPassword);

                if (hexPassword != null)
                {
                    byte[] hexPasswordBytes;

                    error = null;
                    hexPasswordBytes = FromHexString(hexPassword, true, ref error);

                    if (hexPasswordBytes == null)
                    {
                        throw new FormatException(HelperMethods.StringFormat(
                            CultureInfo.CurrentCulture,
                            "Cannot parse 'HexPassword' property value into byte values: {0}",
                            error));
                    }

                    _sql.SetPassword(hexPasswordBytes, false);
                    _passwordWasText = false;
                }
                else
                {
                    string password = FindKey(opts, "Password", DefaultPassword);

                    if (password != null)
                    {
                        byte[] passwordBytes = UTF8Encoding.UTF8.GetBytes(
                            password); /* throw */

                        _sql.SetPassword(passwordBytes, false);
                        _passwordWasText = false;
                    }
                    else if (_password != null)
                    {
                        _sql.SetPassword(_password, _passwordWasText);
                    }

                    password = null; /* IMMUTABLE */
                }

                hexPassword = null; /* IMMUTABLE */
            }
        }

        textPassword = null; /* IMMUTABLE */
        _password = null; /* IMMUTABLE */

        if (hidePassword)
        {
            if (opts.ContainsKey("TextHexPassword"))
                opts["TextHexPassword"] = String.Empty;

            if (opts.ContainsKey("TextPassword"))
                opts["TextPassword"] = String.Empty;

            if (opts.ContainsKey("HexPassword"))
                opts["HexPassword"] = String.Empty;

            if (opts.ContainsKey("Password"))
                opts["Password"] = String.Empty;

            _connectionString = BuildConnectionString(opts);
        }
#else
        if (FindKey(opts, "TextHexPassword", null) != null)
        {
            throw new SQLiteException(SQLiteErrorCode.Error,
                "Cannot use \"TextHexPassword\" connection string property: " +
                "library was not built with encryption support, please " +
                "see \"https://www.sqlite.org/see\" for more information");
        }

        if (FindKey(opts, "TextPassword", null) != null)
        {
            throw new SQLiteException(SQLiteErrorCode.Error,
                "Cannot use \"TextPassword\" connection string property: " +
                "library was not built with encryption support, please " +
                "see \"https://www.sqlite.org/see\" for more information");
        }
Changes to System.Data.SQLite/SQLiteConnectionStringBuilder.cs.
512
513
514
515
516
517
518





























519
520
521
522
523
524
525
            return null;
        }
        set
        {
            this["textpassword"] = value;
        }
    }






























    /// <summary>
    /// Gets/Sets the page size for the connection.
    /// </summary>
    [DisplayName("Page Size")]
    [Browsable(true)]
    [DefaultValue(4096)]







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







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
            return null;
        }
        set
        {
            this["textpassword"] = value;
        }
    }

    /// <summary>
    /// Gets/sets the database encryption textual password in hexadecimal
    /// </summary>
    [DisplayName("Textual Hexadecimal Password")]
    [Browsable(true)]
    [PasswordPropertyText(true)]
    [DefaultValue(null)]
    public byte[] TextHexPassword
    {
        get
        {
            object value;

            if (TryGetValue("texthexpassword", out value))
            {
                if (value is string)
                    return SQLiteConnection.FromHexString((string)value);
                else if (value != null)
                    return (byte[])value;
            }

            return null;
        }
        set
        {
            this["texthexpassword"] = SQLiteConnection.ToHexString(value);
        }
    }

    /// <summary>
    /// Gets/Sets the page size for the connection.
    /// </summary>
    [DisplayName("Page Size")]
    [Browsable(true)]
    [DefaultValue(4096)]
Changes to Tests/basic.eagle.
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060

1061
1062
1063
1064
1065
1066
1067
                   Password "Page Size" "Max Page Count" "Cache Size" \
                   DateTimeFormat DateTimeKind DateTimeFormatString \
                   BaseSchemaName "Journal Mode" "Default IsolationLevel" \
                   "Foreign Keys" Flags SetDefaults ToFullPath HexPassword \
                   DefaultDbType DefaultTypeName NoSharedFlags PrepareRetries \
                   ZipVfsVersion VfsName BusyTimeout ProgressOps \
                   NoDefaultFlags "Recursive Triggers" WaitTimeout \
                   TextPassword]

    set values [list null 3 Normal True False \
                     True test.db test.db file:test.db 60 \
                     120 False True False True \
                     secret 4096 1024 8192 \
                     UnixEpoch Utc yyyy-MM-dd sqlite_schema \
                     Memory Serializable False \
                     Default False False 736563726574 String \
                     TEXT True 20 v2 test 1000 2000 True True 30000 \
                     textsecret]

    set propertyNames [list null Version SyncMode UseUTF16Encoding Pooling \
                            BinaryGUID DataSource Uri FullUri DefaultTimeout \
                            DefaultMaximumSleepTime \
                            Enlist FailIfMissing LegacyFormat ReadOnly \
                            Password PageSize MaxPageCount CacheSize \
                            DateTimeFormat DateTimeKind DateTimeFormatString \
                            BaseSchemaName JournalMode DefaultIsolationLevel \
                            ForeignKeys Flags SetDefaults ToFullPath \
                            HexPassword DefaultDbType DefaultTypeName \
                            NoSharedFlags PrepareRetries ZipVfsVersion \
                            VfsName BusyTimeout ProgressOps NoDefaultFlags \
                            RecursiveTriggers WaitTimeout TextPassword]


    foreach key $keys value $values propertyName $propertyNames {
      set code [catchCSharp {
        object invoke _Dynamic${id}.Test${id} GetConnectionString \
            $key $value $propertyName
      } result]








|









|












|
>







1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
                   Password "Page Size" "Max Page Count" "Cache Size" \
                   DateTimeFormat DateTimeKind DateTimeFormatString \
                   BaseSchemaName "Journal Mode" "Default IsolationLevel" \
                   "Foreign Keys" Flags SetDefaults ToFullPath HexPassword \
                   DefaultDbType DefaultTypeName NoSharedFlags PrepareRetries \
                   ZipVfsVersion VfsName BusyTimeout ProgressOps \
                   NoDefaultFlags "Recursive Triggers" WaitTimeout \
                   TextPassword TextHexPassword]

    set values [list null 3 Normal True False \
                     True test.db test.db file:test.db 60 \
                     120 False True False True \
                     secret 4096 1024 8192 \
                     UnixEpoch Utc yyyy-MM-dd sqlite_schema \
                     Memory Serializable False \
                     Default False False 736563726574 String \
                     TEXT True 20 v2 test 1000 2000 True True 30000 \
                     textsecret 736563726574]

    set propertyNames [list null Version SyncMode UseUTF16Encoding Pooling \
                            BinaryGUID DataSource Uri FullUri DefaultTimeout \
                            DefaultMaximumSleepTime \
                            Enlist FailIfMissing LegacyFormat ReadOnly \
                            Password PageSize MaxPageCount CacheSize \
                            DateTimeFormat DateTimeKind DateTimeFormatString \
                            BaseSchemaName JournalMode DefaultIsolationLevel \
                            ForeignKeys Flags SetDefaults ToFullPath \
                            HexPassword DefaultDbType DefaultTypeName \
                            NoSharedFlags PrepareRetries ZipVfsVersion \
                            VfsName BusyTimeout ProgressOps NoDefaultFlags \
                            RecursiveTriggers WaitTimeout TextPassword \
                            TextHexPassword]

    foreach key $keys value $values propertyName $propertyNames {
      set code [catchCSharp {
        object invoke _Dynamic${id}.Test${id} GetConnectionString \
            $key $value $propertyName
      } result]

1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
Max Page Count=1024\} 0 \{8192, Cache Size=8192\} 0 \{UnixEpoch,\
DateTimeFormat=UnixEpoch\} 0 \{Utc, DateTimeKind=Utc\} 0 \{yyyy-MM-dd,\
DateTimeFormatString=yyyy-MM-dd\} 0 \{sqlite_schema,\
BaseSchemaName=sqlite_schema\} 0 \{Memory, Journal Mode=Memory\} 0\
\{Serializable, Default IsolationLevel=Serializable\} 0 \{False, Foreign\
Keys=False\} 0 \{(?:Default|LogCallbackException),\
Flags=(?:Default|LogCallbackException)\} 0 \{False, SetDefaults=False\} 0\
\{False, ToFullPath=False\} 0 {736563726574, HexPassword=736563726574} 0\
\{String, DefaultDbType=String\} 0 \{TEXT, DefaultTypeName=TEXT\} 0 \{True,\
NoSharedFlags=True\} 0 \{20, PrepareRetries=20\} 0 \{v2, ZipVfsVersion=v2\} 0\
\{test, VfsName=test\} 0 \{1000, BusyTimeout=1000\} 0 \{2000,\
ProgressOps=2000\} 0 \{True, NoDefaultFlags=True\} 0 \{True, Recursive\
Triggers=True\} 0 \{30000, WaitTimeout=30000\} 0 \{textsecret,\
TextPassword=textsecret\}$}}

###############################################################################

runTest {test data-1.18 {SQLiteConvert ToDateTime (Julian Day)} -body {
  set dateTime [object invoke -create System.Data.SQLite.SQLiteConvert \
      ToDateTime 2455928.0 Utc]








|





|







1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
Max Page Count=1024\} 0 \{8192, Cache Size=8192\} 0 \{UnixEpoch,\
DateTimeFormat=UnixEpoch\} 0 \{Utc, DateTimeKind=Utc\} 0 \{yyyy-MM-dd,\
DateTimeFormatString=yyyy-MM-dd\} 0 \{sqlite_schema,\
BaseSchemaName=sqlite_schema\} 0 \{Memory, Journal Mode=Memory\} 0\
\{Serializable, Default IsolationLevel=Serializable\} 0 \{False, Foreign\
Keys=False\} 0 \{(?:Default|LogCallbackException),\
Flags=(?:Default|LogCallbackException)\} 0 \{False, SetDefaults=False\} 0\
\{False, ToFullPath=False\} 0 \{736563726574, HexPassword=736563726574\} 0\
\{String, DefaultDbType=String\} 0 \{TEXT, DefaultTypeName=TEXT\} 0 \{True,\
NoSharedFlags=True\} 0 \{20, PrepareRetries=20\} 0 \{v2, ZipVfsVersion=v2\} 0\
\{test, VfsName=test\} 0 \{1000, BusyTimeout=1000\} 0 \{2000,\
ProgressOps=2000\} 0 \{True, NoDefaultFlags=True\} 0 \{True, Recursive\
Triggers=True\} 0 \{30000, WaitTimeout=30000\} 0 \{textsecret,\
TextPassword=textsecret\} 0 \{736563726574, TextHexPassword=736563726574\}$}}

###############################################################################

runTest {test data-1.18 {SQLiteConvert ToDateTime (Julian Day)} -body {
  set dateTime [object invoke -create System.Data.SQLite.SQLiteConvert \
      ToDateTime 2455928.0 Utc]

5726
5727
5728
5729
5730
5731
5732


























































5733
5734
5735
5736
5737
5738
5739
5740
5741
} -constraints {eagle System.Data.SQLite.Encryption monoBug28 command.sql\
compile.DATA SQLite System.Data.SQLite} -match regexp -result {^1 \{(?:file is\
not a database|database disk image is malformed)\} 1 \{(?:file is not a\
database|database disk image is malformed)\} 0 1 0 2$}}

###############################################################################



























































runTest {test data-1.106 {contrib math functions} -setup {
  setupDb [set fileName data-1.106.db]
} -body {
  set results [list]

  set functionCalls [list \
      acos(0) acosh(1) asin(0) asinh(0) \
      atan(0) atan2(0,0) atn2(0,0) \
      atanh(0) ceil(0) ceiling(0) cos(0) \







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|







5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
} -constraints {eagle System.Data.SQLite.Encryption monoBug28 command.sql\
compile.DATA SQLite System.Data.SQLite} -match regexp -result {^1 \{(?:file is\
not a database|database disk image is malformed)\} 1 \{(?:file is not a\
database|database disk image is malformed)\} 0 1 0 2$}}

###############################################################################

runTest {test data-1.106 {TextHexPassword error (no encryption support)} -body {
  list [catch {
    setupDb [set fileName data-1.106.db] "" "" "" "" "TextHexPassword=1234;"
  } msg] [extractSystemDataSQLiteExceptionMessage $msg]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain msg db fileName
} -constraints [fixConstraints {eagle !System.Data.SQLite.Encryption monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite}] -result {1 {SQL logic\
error -- Cannot use "TextHexPassword" connection string property: library was\
not built with encryption support, please see "https://www.sqlite.org/see" for\
more information}}}

###############################################################################

runTest {test data-1.107 {encrypted database, w/TextHexPassword} -setup {
  setupDb [set fileName data-1.107.db] "" "" "" "" "TextHexPassword=1234;"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=1234;" true false

  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] \
      [extractSystemDataSQLiteExceptionMessage $error]

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] \
      [extractSystemDataSQLiteExceptionMessage $error]

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "TextHexPassword=1234;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] \
      [extractSystemDataSQLiteExceptionMessage $error]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] \
      [extractSystemDataSQLiteExceptionMessage $error]

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle System.Data.SQLite.Encryption monoBug28 command.sql\
compile.DATA SQLite System.Data.SQLite} -match regexp -result {^1 \{(?:file is\
not a database|database disk image is malformed)\} 1 \{(?:file is not a\
database|database disk image is malformed)\} 0 1 0 2$}}

###############################################################################

runTest {test data-1.108 {contrib math functions} -setup {
  setupDb [set fileName data-1.108.db]
} -body {
  set results [list]

  set functionCalls [list \
      acos(0) acosh(1) asin(0) asinh(0) \
      atan(0) atan2(0,0) atn2(0,0) \
      atanh(0) ceil(0) ceiling(0) cos(0) \
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^0 1\.5707\d* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0\
0\.6420\d* 0 1\.3130\d* 0 0 0 1 0 0 0 0 0 0 0 3\.1415\d* 0 1 0 0 0 0 0 0 0 0 0\
0 0 0 0 0 0 0$}}

###############################################################################

runTest {test data-1.107 {contrib math functions w/NoCoreFunctions} -setup {
  setupDb [set fileName data-1.107.db] "" "" "" NoCoreFunctions
} -body {
  set results [list]

  set functionCalls [list \
      acos(0) acosh(1) asin(0) asinh(0) \
      atan(0) atan2(0,0) atn2(0,0) \
      atanh(0) ceil(0) ceiling(0) cos(0) \







|
|







5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^0 1\.5707\d* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0\
0\.6420\d* 0 1\.3130\d* 0 0 0 1 0 0 0 0 0 0 0 3\.1415\d* 0 1 0 0 0 0 0 0 0 0 0\
0 0 0 0 0 0 0$}}

###############################################################################

runTest {test data-1.109 {contrib math functions w/NoCoreFunctions} -setup {
  setupDb [set fileName data-1.109.db] "" "" "" NoCoreFunctions
} -body {
  set results [list]

  set functionCalls [list \
      acos(0) acosh(1) asin(0) asinh(0) \
      atan(0) atan2(0,0) atn2(0,0) \
      atanh(0) ceil(0) ceiling(0) cos(0) \
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite sqlite3_c99_math} -match regexp -result {^0 1\.5707\d* 0 0 0\
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0\.6420\d* 0 1\.3130\d* 0 0 0 1 0 0 0 0\
0 0 0 3\.1415\d* 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0$}}

###############################################################################

runTest {test data-1.108 {core-only math functions} -setup {
  setupDb [set fileName data-1.108.db]
} -body {
  set results [list]

  set functionCalls [list \
      ln(1) log(2,1) log2(1) mod(1,1) \
      pow(0,0) trunc(0)]








|
|







5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite sqlite3_c99_math} -match regexp -result {^0 1\.5707\d* 0 0 0\
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0\.6420\d* 0 1\.3130\d* 0 0 0 1 0 0 0 0\
0 0 0 3\.1415\d* 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0$}}

###############################################################################

runTest {test data-1.110 {core-only math functions} -setup {
  setupDb [set fileName data-1.110.db]
} -body {
  set results [list]

  set functionCalls [list \
      ln(1) log(2,1) log2(1) mod(1,1) \
      pow(0,0) trunc(0)]

5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
  unset -nocomplain functionCall functionCalls
  unset -nocomplain db fileName
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite sqlite3_c99_math} -result {0 0 0 0 0 0 0 0 0 1 0 0}}

###############################################################################

runTest {test data-1.109 {core-only math functions w/NoCoreFunctions} -setup {
  setupDb [set fileName data-1.109.db] "" "" "" NoCoreFunctions
} -body {
  set results [list]

  set functionCalls [list \
      ln(1) log(2,1) log2(1) mod(1,1) \
      pow(0,0) trunc(0)]








|
|







5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
  unset -nocomplain functionCall functionCalls
  unset -nocomplain db fileName
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite sqlite3_c99_math} -result {0 0 0 0 0 0 0 0 0 1 0 0}}

###############################################################################

runTest {test data-1.111 {core-only math functions w/NoCoreFunctions} -setup {
  setupDb [set fileName data-1.111.db] "" "" "" NoCoreFunctions
} -body {
  set results [list]

  set functionCalls [list \
      ln(1) log(2,1) log2(1) mod(1,1) \
      pow(0,0) trunc(0)]

Changes to Tests/tkt-23d8d6171e.eagle.
56
57
58
59
60
61
62




63
64
65
66
67
68
69
  lappend result [expr {
    [string first ";HexPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextPassword=;" [$connection ConnectionString]] != -1
  }]





  set result
} -cleanup {
  freeDbConnection

  unset -nocomplain connection








>
>
>
>







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  lappend result [expr {
    [string first ";HexPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextHexPassword=;" [$connection ConnectionString]] != -1
  }]

  set result
} -cleanup {
  freeDbConnection

  unset -nocomplain connection

112
113
114
115
116
117
118




119
120
121
122
123
124
125
  lappend result [expr {
    [string first ";HexPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextPassword=;" [$connection ConnectionString]] != -1
  }]





  set result
} -cleanup {
  freeDbConnection

  unset -nocomplain connection








>
>
>
>







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
  lappend result [expr {
    [string first ";HexPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextHexPassword=;" [$connection ConnectionString]] != -1
  }]

  set result
} -cleanup {
  freeDbConnection

  unset -nocomplain connection

168
169
170
171
172
173
174
































































175
176
177
178
179
180
181
  lappend result [expr {
    [string first ";HexPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextPassword=;" [$connection ConnectionString]] != -1
  }]

































































  set result
} -cleanup {
  freeDbConnection

  unset -nocomplain connection








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







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
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
  lappend result [expr {
    [string first ";HexPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextHexPassword=;" [$connection ConnectionString]] != -1
  }]

  set result
} -cleanup {
  freeDbConnection

  unset -nocomplain connection

  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle System.Data.SQLite.Encryption monoBug28 command.sql\
compile.DATA SQLite System.Data.SQLite} -result \
{0 1 0 1 0 2 {} False False False True}}

###############################################################################

runTest {test tkt-23d8d6171e-1.4 {HidePassword flag w/TextHexPassword} -setup {
  setupDb [set fileName tkt-23d8d6171e-1.4.db] "" "" "" HidePassword \
      "TextHexPassword=1234;"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] \
      [extractSystemDataSQLiteExceptionMessage $error]

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] \
      [extractSystemDataSQLiteExceptionMessage $error]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] \
      [extractSystemDataSQLiteExceptionMessage $error]

  set connection [getDbConnection]

  lappend result [$connection -flags +NonPublic _password]

  lappend result [expr {
    [string first 1234 [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";Password=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";HexPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextPassword=;" [$connection ConnectionString]] != -1
  }]

  lappend result [expr {
    [string first ";TextHexPassword=;" [$connection ConnectionString]] != -1
  }]

  set result
} -cleanup {
  freeDbConnection

  unset -nocomplain connection

Changes to readme.htm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
ADO.NET SQLite Data Provider<br />
Version 1.0.118.0 - March XX, 2023 <font color="red">(release scheduled)</font><br />
Using <a href="https://www.sqlite.org/releaselog/3_40_0.html">SQLite 3.40.0</a><br />Originally written by Robert Simpson<br />
Released to the public domain, use at your own risk!<br />
Official provider website:&nbsp;<a href="https://system.data.sqlite.org/">https://system.data.sqlite.org/</a><br />
Legacy versions:&nbsp;<a href="https://sourceforge.net/projects/sqlite-dotnet2/">https://sourceforge.net/projects/sqlite-dotnet2/</a><br />
<br />
The current development version can be downloaded from <a href="https://system.data.sqlite.org/index.html/timeline?y=ci">
https://system.data.sqlite.org/index.html/timeline?y=ci</a>







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
ADO.NET SQLite Data Provider<br />
Version 1.0.118.0 - April XX, 2023 <font color="red">(release scheduled)</font><br />
Using <a href="https://www.sqlite.org/releaselog/3_40_0.html">SQLite 3.40.0</a><br />Originally written by Robert Simpson<br />
Released to the public domain, use at your own risk!<br />
Official provider website:&nbsp;<a href="https://system.data.sqlite.org/">https://system.data.sqlite.org/</a><br />
Legacy versions:&nbsp;<a href="https://sourceforge.net/projects/sqlite-dotnet2/">https://sourceforge.net/projects/sqlite-dotnet2/</a><br />
<br />
The current development version can be downloaded from <a href="https://system.data.sqlite.org/index.html/timeline?y=ci">
https://system.data.sqlite.org/index.html/timeline?y=ci</a>
204
205
206
207
208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
designed for robustness and maximum backward compatibility with previously
released versions of System.Data.SQLite.
</p>

<h2><b>Version History</b></h2>

<p>
    <b>1.0.118.0 - March XX, 2023 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Add the ConnectionStringPreview, SqlStringPreview, and Canceled connection events.</li>
    <li>Add support for the sqlite3_is_interrupted core library API. Pursuant to forum post [b6a707bffb].</li>
    <li>Add support for the sqlite_trace_v2 core library API. Pursuant to forum post [1c418d7edc].</li>

</ul>
<p>
    <b>1.0.117.0 - November 28, 2022</b>
</p>
<ul>
    <li>Updated to <a href="https://www.sqlite.org/releaselog/3_40_0.html">SQLite 3.40.0</a>.</li>
    <li>Add support for creating custom window functions. Pursuant to forum post [21de219031].</li>







|





>







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
designed for robustness and maximum backward compatibility with previously
released versions of System.Data.SQLite.
</p>

<h2><b>Version History</b></h2>

<p>
    <b>1.0.118.0 - April XX, 2023 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Add the ConnectionStringPreview, SqlStringPreview, and Canceled connection events.</li>
    <li>Add support for the sqlite3_is_interrupted core library API. Pursuant to forum post [b6a707bffb].</li>
    <li>Add support for the sqlite_trace_v2 core library API. Pursuant to forum post [1c418d7edc].</li>
    <li>Add TextHexPassword connection string property for use with <a href="https://www.sqlite.org/see">SEE</a>.</li>
</ul>
<p>
    <b>1.0.117.0 - November 28, 2022</b>
</p>
<ul>
    <li>Updated to <a href="https://www.sqlite.org/releaselog/3_40_0.html">SQLite 3.40.0</a>.</li>
    <li>Add support for creating custom window functions. Pursuant to forum post [21de219031].</li>
Changes to www/news.wiki.
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
    Access to archived release packages will be granted on a case-by-case basis.
  </li>
</ul>

<div align="center"><h2><b>Version History</b></h2></div>

<p>
    <b>1.0.118.0 - March XX, 2023 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Add the ConnectionStringPreview, SqlStringPreview, and Canceled connection events.</li>
    <li>Add support for the sqlite3_is_interrupted core library API. Pursuant to forum post [https://www.sqlite.org/forum/forumpost/b6a707bffb|b6a707bffb].</li>
    <li>Add support for the sqlite_trace_v2 core library API. Pursuant to forum post [https://www.sqlite.org/forum/forumpost/1c418d7edc|1c418d7edc].</li>

</ul>
<p>
    <b>1.0.117.0 - November 28, 2022</b>
</p>
<ul>
    <li>Updated to [https://www.sqlite.org/releaselog/3_40_0.html|SQLite 3.40.0].</li>
    <li>Add support for creating custom window functions. Pursuant to forum post [https://www.sqlite.org/forum/forumpost/21de219031|21de219031].</li>







|





>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
    Access to archived release packages will be granted on a case-by-case basis.
  </li>
</ul>

<div align="center"><h2><b>Version History</b></h2></div>

<p>
    <b>1.0.118.0 - April XX, 2023 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Add the ConnectionStringPreview, SqlStringPreview, and Canceled connection events.</li>
    <li>Add support for the sqlite3_is_interrupted core library API. Pursuant to forum post [https://www.sqlite.org/forum/forumpost/b6a707bffb|b6a707bffb].</li>
    <li>Add support for the sqlite_trace_v2 core library API. Pursuant to forum post [https://www.sqlite.org/forum/forumpost/1c418d7edc|1c418d7edc].</li>
    <li>Add TextHexPassword connection string property for use with [https://www.sqlite.org/see|SEE].</li>
</ul>
<p>
    <b>1.0.117.0 - November 28, 2022</b>
</p>
<ul>
    <li>Updated to [https://www.sqlite.org/releaselog/3_40_0.html|SQLite 3.40.0].</li>
    <li>Add support for creating custom window functions. Pursuant to forum post [https://www.sqlite.org/forum/forumpost/21de219031|21de219031].</li>