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 pst-76cb35b58d Excluding Merge-Ins

This is equivalent to a diff from 1764d76cee to 2d2cbf5603

2024-05-24
19:15
Fix support for unnamed parameters using the ?NNN syntax. Pursuant to forum post 76cb35b58d. check-in: ded053d6c2 user: mistachkin tags: trunk
2024-05-23
23:15
Work-in-progress on addressing forum post 25cafb35e5. check-in: 6d7348176c user: mistachkin tags: pst-25cafb35e5
2024-05-13
17:29
Improve testing of the changes on this branch. Closed-Leaf check-in: 2d2cbf5603 user: mistachkin tags: pst-76cb35b58d
2024-05-12
15:48
Update version history docs. check-in: 5003348e58 user: mistachkin tags: pst-76cb35b58d
00:39
Work-in-progress on addressing forum post 76cb35b58d. check-in: 1820415db5 user: mistachkin tags: pst-76cb35b58d
2024-04-27
15:15
Update version history docs. check-in: 1764d76cee user: mistachkin tags: trunk
2024-04-15
22:00
Minor adjustments to the test for ticket [ce4d70ea6f]. check-in: abb207e382 user: mistachkin tags: trunk

Changes to Doc/Extra/Provider/version.html.

47
48
49
50
51
52
53

54
55
56
57
58
59
60
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61







+







    <ul>
      <li>Updated to <a href="https://www.sqlite.org/releaselog/3_45_3.html">SQLite 3.45.3</a>.</li>
      <li>Update internal resource list of reserved SQL words.</li>
      <li>Avoid NullReferenceException from Path.Combine method when the PublishSingleFile property is enabled for a project. Pursuant to forum post <a href="https://www.sqlite.org/forum/forumpost/66a0d2716a">[66a0d2716a]</a>.</li>
      <li>Add the VfsName connection string property.</li>
      <li>Fix rarely seen NullReferenceException in the StaticWeakConnectionPool.Add method.</li>
      <li>Revise the calculation used to bind DateTime values. Fix for <a href="https://system.data.sqlite.org/index.html/info/bbddfeb773">[bbddfeb773]</a>.</li>
      <li>Fix support for unnamed parameters using the ?NNN syntax. Pursuant to forum post <a href="https://www.sqlite.org/forum/forumpost/76cb35b58d">[76cb35b58d]</a>.</li>
    </ul>
    <p><b>1.0.118.0 - June 10, 2023</b></p>
    <ul>
      <li>Updated to <a href="https://www.sqlite.org/releaselog/3_42_0.html">SQLite 3.42.0</a>.</li>
      <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>

Changes to Setup/data/verify.lst.

842
843
844
845
846
847
848

849
850
851
852
853
854
855
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856







+







  Tests/function.eagle
  Tests/installer.eagle
  Tests/linq.eagle
  Tests/memory.eagle
  Tests/pool.eagle
  Tests/progress.eagle
  Tests/pst-4db2934c2e.eagle
  Tests/pst-76cb35b58d.eagle
  Tests/pst-eeaefb84ec.eagle
  Tests/pst-f4e718891d.eagle
  Tests/session.eagle
  Tests/speed.eagle
  Tests/stress.eagle
  Tests/template/
  Tests/template/empty.eagle

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

1
2
3
4

5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21



-
+









+







/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 *
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.ComponentModel;
  using System.Globalization;

  /// <summary>
  /// SQLite implementation of DbParameter.
  /// </summary>
  public sealed class SQLiteParameter : DbParameter, ICloneable
  {
    /// <summary>
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87







-
+







    {
        _command = command;
    }

    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteParameter() 
    public SQLiteParameter()
      : this(null, UnknownDbType, 0, null, DataRowVersion.Current)
    {
    }

    /// <summary>
    /// Constructs a named parameter given the specified parameter name
    /// </summary>
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217







-
+







    /// Constructs a named parameter of the specified type, size, source column and row version
    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion)      
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion)
    {
      _parameterName = parameterName;
      _dbType = parameterType;
      _sourceColumn = sourceColumn;
      _rowVersion = rowVersion;
      _dataSize = parameterSize;
      _nullable = true;
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245







-
+







    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="direction">Only input parameters are supported in SQLite</param>
    /// <param name="isNullable">Ignored</param>
    /// <param name="precision">Ignored</param>
    /// <param name="scale">Ignored</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    /// <param name="value">The initial value to assign the parameter</param>   
    /// <param name="value">The initial value to assign the parameter</param>
#if !PLATFORM_COMPACTFRAMEWORK
    [EditorBrowsable(EditorBrowsableState.Advanced)]
#endif
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion rowVersion, object value)
      : this(parameterName, parameterType, parameterSize, sourceColumn, rowVersion)
    {
      Direction = direction;
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338







-
+














-
+







    /// </summary>
    public IDbCommand Command
    {
      get
      {
        return _command;
      }
      set 
      set
      {
        _command = value;
      }
    }

    /// <summary>
    /// Whether or not the parameter can contain a null value
    /// </summary>
    public override bool IsNullable
    {
      get
      {
        return _nullable;
      }
      set 
      set
      {
        _nullable = value;
      }
    }

    /// <summary>
    /// Returns the datatype of the parameter
503
504
505
506
507
508
509
510
511















































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







-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    /// <returns>A new, unassociated SQLiteParameter</returns>
    public object Clone()
    {
      SQLiteParameter newparam = new SQLiteParameter(this);

      return newparam;
    }
  }
}

    /// <summary>
    /// Attempts to build a name suitable for use with an index-only
    /// (unnamed) parameter.
    /// </summary>
    /// <param name="index">The index for the parameter.</param>
    /// <param name="placeholder">
    /// Non-zero if the returned name should be a placeholder, i.e.
    /// an unnamed parameter that does not use a syntax supported by
    /// the SQLite core library.
    /// </param>
    /// <returns>The built name -OR- null if it cannot be built.</returns>
    internal static string CreateNameForIndex(int index, bool placeholder)
    {
        return HelperMethods.StringFormat(CultureInfo.InvariantCulture,
            placeholder ? ";{0}" : "?{0}", index + 1);
    }

    /// <summary>
    /// Returns non-zero if the specified parameter name appears to
    /// refer to an unnamed parameter placeholder.
    /// </summary>
    /// <param name="name">
    /// The parameter name to check.
    /// </param>
    /// <param name="index">
    /// The parameter index or negative one if it cannot be determined.
    /// </param>
    /// <returns>
    /// Non-zero if the specified parameter name represents an unnamed
    /// placeholder parameter.
    /// </returns>
    internal static bool IsUnnamedPlaceholder(string name, out int index)
    {
        index = -1;

        if (String.IsNullOrEmpty(name))
            return false;

        if (name[0] != ';')
            return false;

        return int.TryParse(
            name.Substring(1), NumberStyles.None, null, out index);
    }
  }
}

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

419
420
421
422
423
424
425
426

427
428

429
430

431
432
433
434
435
436
437
419
420
421
422
423
424
425

426
427

428
429

430
431
432
433
434
435
436
437







-
+

-
+

-
+







      string s;
      int n;
      int y = -1;
      SQLiteStatement stmt;

      foreach(SQLiteParameter p in _parameterList)
      {
        y ++;
        y++;
        s = p.ParameterName;
        if (s == null)
        if (String.IsNullOrEmpty(s))
        {
          s = HelperMethods.StringFormat(CultureInfo.InvariantCulture, ";{0}", nUnnamed);
          s = SQLiteParameter.CreateNameForIndex(nUnnamed, true);
          nUnnamed++;
        }

        int x;
        bool isMapped = false;

        if (activeStatement == null)
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
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







-
+







-
+
+
+

+









          stmt = null;
        }

        // If the parameter has a name, but the SQL statement uses unnamed references, this can happen -- attempt to map
        // the parameter by its index in the collection
        if (isMapped == false)
        {
          s = HelperMethods.StringFormat(CultureInfo.InvariantCulture, ";{0}", y);
          s = SQLiteParameter.CreateNameForIndex(y, true);

          stmt = activeStatement;
          for (n = 0; n < x; n++)
          {
            if (stmt == null) stmt = _command._statementList[n];
            if (stmt._paramNames != null)
            {
              if (stmt.MapParameter(s, p) == true)
              if (stmt.MapParameter(s, p) ||
                  stmt.MapUnnamedParameter(s, p))
              {
                isMapped = true;
              }
            }
            stmt = null;
          }
        }
      }
      if (activeStatement == null) _unboundFlag = false;
    }
  }
}

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

102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116







-
+







        _paramValues = new SQLiteParameter[n];

        for (x = 0; x < n; x++)
        {
          s = _sql.Bind_ParamName(this, _flags, x + 1);
          if (String.IsNullOrEmpty(s))
          {
            s = HelperMethods.StringFormat(CultureInfo.InvariantCulture, ";{0}", nCmdStart);
            s = SQLiteParameter.CreateNameForIndex(nCmdStart, true);
            nCmdStart++;
            _unnamedParameters++;
          }
          _paramNames[x] = s;
          _paramValues[x] = null;
        }
      }
206
207
208
209
210
211
212






































213
214
215
216
217
218
219
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







        if ((_sql != null) && _sql.IsOpen())
        {
            changes = _sql.Changes;
            readOnly = _sql.IsReadOnly(this);

            return true;
        }

        return false;
    }

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

    /// <summary>
    /// This method attempts to map the specified named placeholder
    /// parameter, i.e. an unnamed parameter that has been given an
    /// placeholder name.
    /// </summary>
    /// <param name="s">The placeholder parameter name to map.</param>
    /// <param name="p">The parameter to assign it.</param>
    internal bool MapUnnamedParameter(string s, SQLiteParameter p)
    {
        if (_paramNames == null)
            return false;

        int index;

        if (SQLiteParameter.IsUnnamedPlaceholder(s, out index))
        {
            s = String.Format("?{0}", index);

            int length = s.Length;
            int count = _paramNames.Length;

            for (int n = 0; n < count; n++)
            {
                if (String.Compare(
                      _paramNames[n], 0, s, 0, length,
                      StringComparison.Ordinal) == 0)
                {
                    _paramValues[n] = p;
                    return true;
                }
            }
        }

        return false;
    }

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

    /// <summary>

Added Tests/pst-76cb35b58d.eagle.























































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# pst-76cb35b58d.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require Eagle.Library
package require Eagle.Test

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

runTest {test pst-76cb35b58d-1.1 {duplicate unnamed parameters} -setup {
  setupDb [set fileName pst-76cb35b58d-1.1.db]
} -body {
  sql execute $db {
    CREATE TABLE t1(x INTEGER, y TEXT, z TEXT, w TEXT);
    INSERT INTO t1 (x, y) VALUES(1, 'one');
    INSERT INTO t1 (x, y) VALUES(2, 'two');
    INSERT INTO t1 (x, y) VALUES(3, 'three');
  }

  set param1 [list "" Int64 99]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(4, 'four');" $param1
  sql execute $db "INSERT INTO t1 (x, y) VALUES(5, ?1);" $param1

  set param1 [list "" Int64 6]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(?1, ?1);" $param1

  set param1 [list "" Int64 7]
  set param2 [list "" String "something else"]

  sql execute $db \
      "INSERT INTO t1 (x, y, z, w) VALUES(?1, ?1, ?2, ?2);" \
      $param1 $param2

  sql execute -execute reader -format list \
      $db "SELECT x, y, z FROM t1 ORDER BY x;"
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain param1 param2
  unset -nocomplain db fileName
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -result {1 one 2 two 3 three 4 four 5 99 6 6 7 7 {something\
else}}}

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

runTest {test pst-76cb35b58d-1.2 {duplicate unnamed parameters} -setup {
  setupDb [set fileName pst-76cb35b58d-1.2.db]
} -body {
  sql execute $db {
    CREATE TABLE t1(x INTEGER, y TEXT);
    INSERT INTO t1 (x, y) VALUES(1, '1');
    INSERT INTO t1 (x, y) VALUES(2, '2');
    INSERT INTO t1 (x, y) VALUES(3, '3');
    INSERT INTO t1 (x, y) VALUES(4, '4');
  }

  set sql(0) {
    SELECT x, y FROM t1 WHERE x = 1 OR y = 1 ORDER BY x;
  }

  set sql(1) {
    SELECT x, y FROM t1 WHERE x = ? OR y = ? ORDER BY x;
  }

  set sql(2) {
    SELECT x, y FROM t1 WHERE x = ?1 OR y = ?1 ORDER BY x;
  }

  set sql(3) {
    SELECT x, y FROM t1 WHERE x = ?1 OR y = ?2 ORDER BY x;
  }

  set sql(4) {
    SELECT x, y FROM t1 WHERE x = ?2 OR y = ?1 ORDER BY x;
  }

  set sql(5) {
    SELECT x, y FROM t1 WHERE x = ?2 OR y = ?2 ORDER BY x;
  }

  set result [list]
  set param1 [list arg1 Int64 3]
  set param2 [list arg2 Int64 4]

  foreach name [lsort -integer [array names sql]] {
    lappend result [sql execute -execute reader \
        -format list $db $sql($name) $param1 $param2]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain sql name result param1 param2
  unset -nocomplain db fileName
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -result {{1 1} {3 3 4 4} {3 3} {3 3 4 4} {3 3 4 4} {4 4}}}

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

runSQLiteTestEpilogue
runTestEpilogue

Changes to lib/System.Data.SQLite/common.eagle.

5102
5103
5104
5105
5106
5107
5108









5109
5110
5111
5112
5113
5114
5115
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124







+
+
+
+
+
+
+
+
+







        file copy $old_test_log $new_test_log; file delete $old_test_log
        set ::test_log $new_test_log

        if {[info exists ::test_log_path]} then {
          set ::test_log_path $path
        }

        #
        # NOTE: Since renaming the test log file during a test run
        #       is unusual -AND- this condition cannot be detected
        #       by the core script library without our help, issue
        #       the manual notification to the core script library
        #       now.
        #
        catch {newTestLog $old_test_log $new_test_log}

        tputs $::test_channel [appendArgs \
            "---- moved test log from \"" $old_test_log "\" to \"" \
            $new_test_log \"\n]
      }
    }

    proc showSQLiteBuildParameters { channel } {

Changes to readme.htm.

213
214
215
216
217
218
219

220
221
222
223
224
225
226
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227







+







<ul>
    <li>Updated to <a href="https://www.sqlite.org/releaselog/3_45_3.html">SQLite 3.45.3</a>.</li>
    <li>Update internal resource list of reserved SQL words.</li>
    <li>Avoid NullReferenceException from Path.Combine method when the PublishSingleFile property is enabled for a project. Pursuant to forum post [66a0d2716a].</li>
    <li>Add the VfsName connection string property.</li>
    <li>Fix rarely seen NullReferenceException in the StaticWeakConnectionPool.Add method.</li>
    <li>Revise the calculation used to bind DateTime values. Fix for [bbddfeb773].</li>
    <li>Fix support for unnamed parameters using the ?NNN syntax. Pursuant to forum post [76cb35b58d].</li>
</ul>
<p>
    <b>1.0.118.0 - June 10, 2023</b>
</p>
<ul>
    <li>Updated to <a href="https://www.sqlite.org/releaselog/3_42_0.html">SQLite 3.42.0</a>.</li>
    <li>Add the ConnectionStringPreview, SqlStringPreview, and Canceled connection events.</li>

Changes to www/news.wiki.

60
61
62
63
64
65
66

67
68
69
70
71
72
73
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74







+







<ul>
    <li>Updated to [https://www.sqlite.org/releaselog/3_45_3.html|SQLite 3.45.3].</li>
    <li>Update internal resource list of reserved SQL words.</li>
    <li>Avoid NullReferenceException from Path.Combine method when the PublishSingleFile property is enabled for a project. Pursuant to forum post [https://www.sqlite.org/forum/forumpost/66a0d2716a|66a0d2716a].</li>
    <li>Add the VfsName connection string property.</li>
    <li>Fix rarely seen NullReferenceException in the StaticWeakConnectionPool.Add method.</li>
    <li>Revise the calculation used to bind DateTime values. Fix for [bbddfeb773].</li>
    <li>Fix support for unnamed parameters using the ?NNN syntax. Pursuant to forum post [https://www.sqlite.org/forum/forumpost/76cb35b58d|76cb35b58d].</li>
</ul>
<p>
    <b>1.0.118.0 - June 10, 2023</b>
</p>
<ul>
    <li>Updated to [https://www.sqlite.org/releaselog/3_42_0.html|SQLite 3.42.0].</li>
    <li>Add the ConnectionStringPreview, SqlStringPreview, and Canceled connection events.</li>