System.Data.SQLite

Check-in Differences
Login

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

Difference From b5ae536a3dfaf394 To 294c29fd211985b6

2013-11-15
21:01
Add support for compiling the core projects for Windows Embedded Compact 2013 using the appropriate SDK with Visual Studio 2012. check-in: 0adcab7b75 user: mistachkin tags: trunk
20:52
Add link to Windows Embedded Compact information on the download page. check-in: 294c29fd21 user: mistachkin tags: trunk
08:38
When checking for builds and releases available for testing, make sure the matching interop assembly or core library exists, if necessary (i.e. the primary assembly is not mixed-mode). check-in: 5fc3695abf user: mistachkin tags: trunk
2013-09-13
01:38
Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter. check-in: 00b02c1aa6 user: mistachkin tags: trunk
00:58
Make sure the database cannot be changed by a query when the CommandBehavior.SchemaOnly flag is used. Fix for [f8dbab8baf]. check-in: 30e2ba0f43 user: mistachkin tags: tkt-f8dbab8baf
2013-09-12
21:30
Update SQLite core library to the latest trunk code. check-in: b5ae536a3d user: mistachkin tags: trunk
2013-09-10
06:33
Update Eagle in externals to the beta 28 release. check-in: e7fa8c655e user: mistachkin tags: trunk

Changes to .fossil-settings/ignore-glob.
1
2
3
4
5
6
7
8

1
2
3
4
5
6
7
-







*.mistachkin.eagle
*.sln
Externals/Eagle/bin/Eagle*.pdb
Externals/Eagle/bin/x64/Spilornis.pdb
Externals/Eagle/bin/x86/Spilornis.pdb
SQLite.Interop/*.vcxproj
SQLite.Interop/*.vcxproj.filters
System.Data.SQLite/*.csproj
Changes to Doc/Extra/dbfactorysupport.html.
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95







-
+







<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite"/>
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" 
           description=".Net Framework Data Provider for SQLite"
           type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite,
                 Version=1.0.89.0, Culture=neutral,
                 Version=1.0.90.0, Culture=neutral,
                 PublicKeyToken=db937bc2d44ff139"/>
    </DbProviderFactories>
  </system.data>
</configuration>
</pre>
      </div>
      <p>
Changes to Doc/Extra/version.html.
39
40
41
42
43
44
45
46

47
48












49
50
51
52

53


54



55
56
57
58
59
60
61
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







-
+

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




+

+
+

+
+
+







          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
    <h1 class="heading">Version History</h1>
    <p><b>1.0.89.0 - September XX, 2013 <font color="red">(release scheduled)</font></b></p>
    <p><b>1.0.90.0 - January XX, 2014 <font color="red">(release scheduled)</font></b></p>
    <ul>
      <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.8.1</a>.</li>
      <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.8.2</a>.</li>
      <li>Add experimental support for the native regexp extension.</li>
      <li>Never create a new connection wrapper in the SQLiteConnection.Shutdown method.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class.</li>
      <li>Add memory leak detection to the test project for the .NET Compact Framework.</li>
      <li>Add SQLITE_ENABLE_MEMORY_MANAGEMENT compile-time option to the interop assembly.</li>
      <li>Better handling of non-error log messages from the SQLite core library. Pursuant to <a href="http://system.data.sqlite.org/index.html/info/44df10ea90">[44df10ea90]</a>.</li>
    </ul>
    <p><b>1.0.89.0 - October 28, 2013</b></p>
    <ul>
      <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_1.html">SQLite 3.8.1</a>.</li>
      <li>Add AutoCommit property to the SQLiteConnection class. Fix for <a href="http://system.data.sqlite.org/index.html/info/9ba9346f75">[9ba9346f75]</a>.</li>
      <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for <a href="http://system.data.sqlite.org/index.html/info/3113734605">[3113734605]</a>.</li>
      <li>Check the result of sqlite3_column_name function against NULL.</li>
      <li>Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.</li>
      <li>Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for <a href="http://system.data.sqlite.org/index.html/info/aba4549801">[aba4549801]</a>.</li>
      <li>Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter.</li>
      <li>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>Make sure the database cannot be changed by a query when the CommandBehavior.SchemaOnly flag is used. Fix for <a href="http://system.data.sqlite.org/index.html/info/f8dbab8baf">[f8dbab8baf]</a>.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>Fix bug in <a href="http://sourceforge.net/projects/ndoc3/">NDoc3</a> that was preventing some of the MSDN documentation links from working.</li>
      <li>Include the XML documentation files in the NuGet packages. Fix for <a href="http://system.data.sqlite.org/index.html/info/5970d5b0a6">[5970d5b0a6]</a>.</li>
      <li>Add InteropVersion, InteropSourceId, ProviderVersion, and ProviderSourceId properties to the SQLiteConnection class.</li>
      <li>Add experimental support for interfacing with the authorizer callback in the SQLite core library.</li>
      <li>Add experimental support for the native totype extension.</li>
    </ul>
    <p><b>1.0.88.0 - August 7, 2013</b></p>
    <ul>
      <li>Various fixes to managed virtual table integration infrastructure.</li>
      <li>Implement workaround for an incorrect PROCESSOR_ARCHITECTURE being reported. Fix for <a href="http://system.data.sqlite.org/index.html/info/9ac9862611">[9ac9862611]</a>.</li>
      <li>Modify classes that implement the IDisposable pattern to set the disposed flag after their base classes have been disposed.</li>
      <li>When automatically registering custom functions, use the executing assembly (i.e. System.Data.SQLite) for reference detection. Fix for <a href="http://system.data.sqlite.org/index.html/info/4e49a58c4c">[4e49a58c4c]</a>.</li>
Changes to Doc/Extra/welcome.html.
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170







-
+







        <font color="red">
          Itanium processor support not currently included.
        </font>
      </p>
      <h1 class="heading">Distributing the Binaries (Compact Framework)</h1>
      <p>Both the <b>System.Data.SQLite.DLL </b>and <b>SQLite.Interop.XXX.DLL</b> files
        must be deployed on the Compact Framework.&nbsp; The XXX is the build number of
        the System.Data.SQLite library (e.g. &quot;089&quot;).&nbsp; The
        the System.Data.SQLite library (e.g. &quot;090&quot;).&nbsp; The
        <b>SQLite.Interop.XXX.DLL</b> file is a fully native assembly compiled for
        the ARM processor, and System.Data.SQLite is the fully-managed Compact
        Framework assembly.</p>
      <hr />
      <div id="footer">
        <p>
          <a href="mailto:sqlite-users@sqlite.org?subject=SQLite.NET%20Class%20Library%20Documentation%20Feedback:%20Welcome">
Changes to Doc/SQLite.NET.chm.

cannot compute difference between binary files

Changes to Doc/buildChm.tcl.
29
30
31
32
33
34
35
















































36

37

38

39
40
41


42
43
44
45
46
47
48
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







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

+
-
+

-
-
+
+







proc readFileAsSubSpec { fileName } {
  set data [readFile $fileName]
  regsub -all -- {&} $data {\\\&} data
  regsub -all -- {\\(\d+)} $data {\\\\\1} data
  return $data
}

proc getFileHash { fileName } {
  if {[catch {
    exec fossil.exe sha1sum [file nativename $fileName]
  } result] == 0} then {
    return [string trim [lindex [split $result " "] 0]]
  }
  return ""
}

#
# HACK: Copy our local [fixed] copy of the MSDN documenter assembly into the
#       installed location of NDoc3, if necessary.  Actually copying the file
#       will require elevated administrator privileges; otherwise, it will
#       fail.  Any errors encountered while copying the file are reported via
#       the console; however, they will not halt further processing (i.e. the
#       CHM file will probably still get built, but it may contain some links
#       to built-in types that are blank).
#
proc copyMsdnDocumenter { sourceDirectory destinationDirectory } {
  set fileNameOnly NDoc3.Documenter.Msdn.dll

  set sourceFileName [file join $sourceDirectory bin $fileNameOnly]
  set destinationFileName [file join $destinationDirectory bin $fileNameOnly]

  set sourceFileHash [getFileHash $sourceFileName]
  # puts stdout "Hashed \"$sourceFileName\" ==> \"$sourceFileHash\""

  set destinationFileHash [getFileHash $destinationFileName]
  # puts stdout "Hashed \"$destinationFileName\" ==> \"$destinationFileHash\""

  if {[string length $sourceFileHash] > 0 && \
      [string length $destinationFileHash] > 0 && \
      $sourceFileHash ne $destinationFileHash} then {
    if {[catch {
      file copy -force $destinationFileName $destinationFileName.bak
      file copy -force $sourceFileName $destinationFileName
    } result] == 0} then {
      puts stdout \
          "finished copying \"$sourceFileName\" to \"$destinationFileName\""
    } else {
      puts stdout $result
    }
  } else {
    puts stdout \
        "skipped copying \"$sourceFileName\" to \"$destinationFileName\""
  }
}

set path [file dirname [info script]]
set path [file normalize [file dirname [info script]]]

set nDocExtPath [file join [file dirname $path] Externals NDoc3]
set nDocPath [file join $env(ProgramFiles) NDoc3]
set nDocInstPath [file join $env(ProgramFiles) NDoc3]

if {![file isdirectory $nDocPath]} then {
  puts stdout "NDoc3 must be installed to: $nDocPath"
if {![file isdirectory $nDocInstPath]} then {
  puts stdout "NDoc3 must be installed to: $nDocInstPath"
  exit 1
}

set hhcPath [file join $env(ProgramFiles) "HTML Help Workshop"]

if {![file isdirectory $hhcPath]} then {
  puts stdout "HTML Help Workshop must be installed to: $hhcPath"
93
94
95
96
97
98
99
100


101




102

103
104
105
106
107
108
109

110
111
112
113
114
115
116
142
143
144
145
146
147
148

149
150
151
152
153
154
155

156
157
158
159
160
161
162

163
164
165
166
167
168
169
170







-
+
+

+
+
+
+
-
+






-
+







  puts stdout "*WARNING* File \"$xmlDocFile\" does not match: $pattern"
}

#
# TODO: If the NDoc version number ever changes, the next line of code will
#       probably need to be updated.
#
set outputPath [file join Output ndoc3_msdn_temp]
set outputPath [file join Output]
set temporaryPath [file join $outputPath ndoc3_msdn_temp]

if {[file isdirectory $nDocExtPath]} then {
  copyMsdnDocumenter $nDocExtPath $nDocInstPath
}

set code [catch {exec [file join $nDocPath bin NDoc3Console.exe] \
set code [catch {exec [file join $nDocInstPath bin NDoc3Console.exe] \
    "-project=[file nativename $projectFile]"} result]

puts stdout $result; if {$code != 0} then {exit $code}

set fileNames [list SQLite.NET.hhp SQLite.NET.hhc]

foreach fileName [glob -nocomplain [file join $outputPath *.html]] {
foreach fileName [glob -nocomplain [file join $temporaryPath *.html]] {
  lappend fileNames [file tail $fileName]
}

set patterns(.hhc,1) {<!--This document contains Table of Contents information\
for the HtmlHelp compiler\.--><UL>}

set patterns(.hhp,1) {Default topic=~System\.Data\.SQLite\.html}
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218







-
+







set subSpecs(.html,4) {"\1~Overloads.html"}
set subSpecs(.html,5) {"\1~Overloads.html"}
set subSpecs(.html,6) {"\1~Overloads.html"}
set subSpecs(.html,7) {"\1~Overloads.html"}
set subSpecs(.html,8) {"\1~Overloads.html"}

foreach fileName $fileNames {
  set fileName [file join $path $outputPath $fileName]
  set fileName [file join $path $temporaryPath $fileName]

  #
  # NOTE: Make sure the file we need actually exists.
  #
  if {![file isfile $fileName]} then {
    puts stdout "Cannot find file: $fileName"
    exit 1
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214

215
216
217
218
254
255
256
257
258
259
260

261
262
263
264
265
266
267

268
269
270
271
272







-
+






-
+




  #
  if {$count > 0} then {
    writeFile $fileName $data
  }
}

set code [catch {exec [file join $hhcPath hhc.exe] \
    [file nativename [file join $path $outputPath SQLite.NET.hhp]]} result]
    [file nativename [file join $path $temporaryPath SQLite.NET.hhp]]} result]

#
# NOTE: For hhc.exe, zero means failure.
#
puts stdout $result; if {$code == 0} then {exit 1}

file copy -force [file join $path $outputPath SQLite.NET.chm] \
file copy -force [file join $path $temporaryPath SQLite.NET.chm] \
    [file join $path SQLite.NET.chm]

puts stdout SUCCESS
exit 0
Changes to Externals/Eagle/bin/Eagle.dll.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/EagleShell.exe.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/EagleShell.exe.mda.config.
8
9
10
11
12
13
14












15
16
17
18
19
20
21
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







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







 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: $
 *
-->
<mdaConfig xmlns="http://schemas.microsoft.com/CLR/2004/10/mda">
  <!--
      NOTE: The "jitCompilationStart" and "memberInfoCacheCreation" managed
            debugging assistants are extremely noisy.

            Using the "pInvokeLog" managed debugging assistant with no filter
            shows the signature of all P/Invoke calls.  Unfortunately, as of
            the .NET Framework 4.5, it does not appear to support the standard
            wildcard (i.e. "glob") syntax in the filter "dllName" attribute.
            Also, it does not appear to monitor any native calls invoked via
            managed delegates (i.e. those created via the Marshal class using
            the GetDelegateForFunctionPointer method).
  -->
  <assistants>
    <!--++
    <asynchronousThreadAbort />
    <bindingFailure />
    <callbackOnCollectedDelegate listSize="50" />
    <contextSwitchDeadlock enable="true" />
    <dangerousThreadingAPI />
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90







+









-







    </marshaling>
    <memberInfoCacheCreation />
    <moduloObjectHashcode modulus="1" />
    <nonComVisibleBaseClass />
    <notMarshalable />
    <openGenericCERCall />
    <overlappedFreeError />
    <pInvokeLog />
    <pInvokeLog>
      <filter>
        <match dllName="advapi32.dll" />
        <match dllName="advpack.dll" />
        <match dllName="kernel32.dll" />
        <match dllName="mscoree.dll" />
        <match dllName="msvcrt.dll" />
        <match dllName="ntdll.dll" />
        <match dllName="shell32.dll" />
        <match dllName="spilornis.dll" />
        <match dllName="user32.dll" />
        <match dllName="wintrust.dll" />
      </filter>
    </pInvokeLog>
    <pInvokeStackImbalance />
    <raceOnRCWCleanup />
    <reentrancy />
Changes to Externals/Eagle/bin/x64/Spilornis.dll.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/x86/Spilornis.dll.

cannot compute difference between binary files

Changes to Externals/Eagle/lib/Eagle1.0/init.eagle.
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
1202
1203






1204

1205
1206
1207
1208
1209
1210
1211
1212
1213
1214






























1215
1216

1217
1218
1219
1220
1221






1222
1223
1224
1225
1226
1227
1228
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
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228

1229
1230
1231
1232
1233

1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246







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

-
-
+
+







-
+


-
-
+
+



-
-
-
+
+
+
+
+
+

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

-
+




-
+
+
+
+
+
+








      set command [list exec -- \
          [file join $directory Hippogriff.exe] -delay 2000]

      eval $command &; exit -force
    }

    #
    # NOTE: This proc is used to check for new versions of the runtime
    #       when the user executes the interactive "#check" command.  To
    #       disable that functionality, redefine this proc to do nothing.
    #
    proc checkForUpdate {} {
      #
      # NOTE: This should work properly in Eagle only.
      #
      set uri [appendArgs [info engine Uri] [info engine UpdateFile]]
      set fileName [file tempname]; # unique local temp file name.

    proc getUpdateData { uri } {
      #
      # NOTE: Temporarily start trusting ONLY our self-signed certificate
      #       which is used primarily for "software updates".
      # NOTE: Temporarily start trusting ONLY our own self-signed
      #       certificate which is used primarily for updates.
      #
      uri softwareupdates true

      try {
        #
        # NOTE: Download the tag file from the web site.
        #
        uri download $uri $fileName; # synchronous.
        return [uri download -inline $uri]; # synchronous.
      } finally {
        #
        # NOTE: Stop trusting ONLY our self-signed certificate which is
        #       used primarily for "software updates".
        # NOTE: Stop trusting ONLY our own self-signed certificate
        #       which is used primarily for updates.
        #
        uri softwareupdates false
      }

      #
      # NOTE: Read all the data out of the downloaded text file.
    }

    proc getUpdateScriptData { uri } {
      #
      # NOTE: Temporarily start trusting ONLY our own self-signed
      #       certificate which is used primarily for updates.
      #
      uri softwareupdates true
      set data [readFile $fileName]

      #
      # NOTE: Remove the downloaded temporary file.  We no longer need
      #       it because we just read all the data from it.
      #
      file delete $fileName

      #
      # NOTE: Normalize to Unix line-endings.

      try {
        #
        # NOTE: Download the script file from the web site.
        #
        return [interp readorgetscriptfile $uri]; # synchronous.
      } finally {
        #
        # NOTE: Stop trusting ONLY our own self-signed certificate
        #       which is used primarily for updates.
        #
        uri softwareupdates false
      }
    }

    #
    # NOTE: This proc is used to check for new versions -OR- new update
    #       scripts for the runtime when a user executes the interactive
    #       "#check" command.  To disable this functionality, simply
    #       redefine this procedure to do nothing.
    #
    proc checkForUpdate { {wantScripts false} } {
      #
      # NOTE: This should work properly in Eagle only.
      #
      set updateUri [appendArgs [info engine Uri] [info engine UpdateFile]]

      #
      # NOTE: Fetch the master update data from the distribution site
      #       and normalize to Unix-style line-endings.
      #
      set data [string map [list \r\n \n] $data]; # Unix.
      set updateData [string map [list \r\n \n] [getUpdateData $updateUri]]

      #
      # NOTE: Split the data into lines.
      #
      set lines [split $data \n]
      set lines [split $updateData \n]

      #
      # NOTE: Keep track of how many update scripts are processed.
      #
      set scriptCount 0

      #
      # NOTE: Check each line to find the build information...
      #
      foreach line $lines {
        #
        # NOTE: Remove excess whitespace.
1236
1237
1238
1239
1240
1241
1242
1243

1244
1245
1246
1247




1248
1249
1250
1251
1252
1253
1254
1254
1255
1256
1257
1258
1259
1260

1261
1262



1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273







-
+

-
-
-
+
+
+
+







          #
          # NOTE: Skip comment lines.
          #
          if {[string index $line 0] ne "#" && \
              [string index $line 0] ne ";"} then {
            #
            # NOTE: Split the tab-delimited line into fields.  The format
            #       of the lines must be as follows:
            #       of all lines in the data must be as follows:
            #
            # protocolId <tab> publicKeyToken <tab> name <tab> culture
            # <tab> patchLevel <tab> timeStamp <tab> uri <tab> md5Hash
            # <tab> sha1Hash <tab> sha512Hash <tab> notes <newLine>
            #       <startLine> protocolId <tab> publicKeyToken <tab> name
            #       <tab> culture <tab> patchLevel <tab> timeStamp <tab>
            #       baseUri <tab> md5Hash <tab> sha1Hash <tab> sha512Hash
            #       <tab> notes <newLine>
            #
            set fields [split $line \t]

            #
            # NOTE: Grab the protocol Id field.
            #
            set protocolId [lindex $fields 0]
1264
1265
1266
1267
1268
1269
1270










1271
1272
1273
1274
1275
1276
1277
1278
1279
1280

1281
1282
1283
1284
1285
1286
1287
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308

1309
1310
1311
1312
1313
1314
1315
1316







+
+
+
+
+
+
+
+
+
+









-
+







            set name [lindex $fields 2]

            #
            # NOTE: Grab the culture field.
            #
            set culture [lindex $fields 3]

            #
            # NOTE: Figure out which protocol is in use for this line.
            #       The value "1" means this line specifies a build of
            #       the script engine.  The value "2" means this line
            #       specifies an update script (via a URI) to evaluate.
            #       All other values are currently reserved and ignored.
            #
            set checkBuild [expr {!$wantScripts && $protocolId eq "1"}]
            set checkScript [expr {$wantScripts && $protocolId eq "2"}]

            #
            # NOTE: We only want to find the first line that matches our
            #       engine.  The public key token is being used here to
            #       make sure we get the same "flavor" of the engine.
            #       The lines are organized so that the "latest stable
            #       version" is on the first line (for a given public key
            #       token), followed by development builds, experimental
            #       builds, etc.
            #
            if {$protocolId eq "1" && \
            if {($checkBuild || $checkScript) && \
                [matchEnginePublicKeyToken $publicKeyToken] && \
                [matchEngineName $name] && \
                [matchEngineCulture $culture]} then {
              #
              # NOTE: Grab the patch level field.
              #
              set patchLevel [lindex $fields 4]
1297
1298
1299
1300
1301
1302
1303
1304


1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320

1321
1322
1323
1324
1325
1326
1327
1326
1327
1328
1329
1330
1331
1332

1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349

1350
1351
1352
1353
1354
1355
1356
1357







-
+
+















-
+








              #
              # NOTE: Compare the patch level from the line to the one we
              #       are currently using.
              #
              set compare [package vcompare $patchLevel $enginePatchLevel]

              if {$compare > 0} then {
              if {($checkBuild && $compare > 0) || \
                  ($checkScript && $compare == 0)} then {
                #
                # NOTE: Grab the time-stamp field.
                #
                set timeStamp [lindex $fields 5]

                if {[string length $timeStamp] == 0} then {
                  set timeStamp 0; #never?
                }

                #
                # NOTE: Grab the base URI field (i.e. it may be a mirror
                #       site).
                #
                set baseUri [lindex $fields 6]

                if {[string length $baseUri] == 0} then {
                if {$checkBuild && [string length $baseUri] == 0} then {
                  set baseUri [info engine Uri]; # primary site.
                }

                #
                # NOTE: Grab the notes field (which may be empty).
                #
                set notes [lindex $fields 10]
1337
1338
1339
1340
1341
1342
1343
1344
1345














1346











1347
1348
1349
1350












































































































































































1351
1352
1353
1354
1355
1356
1357

1358
1359
1360
1361
1362
1363
1364
1365
1366
1367














1368


1369
1370
1371
1372
1373
1374
1375
1367
1368
1369
1370
1371
1372
1373


1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399




1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
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
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
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577

1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602

1603
1604
1605
1606
1607
1608
1609
1610
1611







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

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






-
+










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







                if {[string is integer -strict $timeStamp]} then {
                  set dateTime [clock format $timeStamp]
                } else {
                  set dateTime [clock format [clock scan $timeStamp]]
                }

                #
                # NOTE: The patch level from the line is greater, we are
                #       out-of-date.
                # NOTE: The engine patch level from the line is greater,
                #       we are out-of-date.  Return the result of our
                #       checking now.
                #
                if {$checkBuild} then {
                  return [list [appendArgs "newer build " $patchLevel \
                      " is available as of " $dateTime] [list $baseUri \
                      $patchLevel] [list $notes]]
                }

                #
                # NOTE: The script patch level from the line matches the
                #       current engine patch level exactly, this script
                #       should be evaluated if it can be authenticated.
                #
                if {$checkScript} then {
                  #
                  # NOTE: First, set the default channel for update script
                  #       status messages.  If the test channel has been
                  #       set (i.e. by the test suite), it will be used
                  #       instead.
                  #
                  if {![info exists channel]} then {
                    set channel [expr {[info exists ::test_channel] ? \
                        $::test_channel : "stdout"}]
                  }
                return [list [appendArgs "newer build " $patchLevel \
                    " is available as of " $dateTime] [list $baseUri \
                    $patchLevel] [list $notes]]
              } elseif {$compare < 0} then {

                  #
                  # NOTE: Next, verify the script has a valid base URI.
                  #       For update scripts, this must be the location
                  #       where the update script data can be downloaded.
                  #
                  if {[string length $baseUri] == 0} then {
                    tqputs $channel [appendArgs \
                        "---- invalid baseUri value for update script line: " \
                        $line \"\n]

                    continue
                  }

                  #
                  # NOTE: Next, grab the md5 field and see if it looks valid.
                  #       Below, the value of this field will be compared to
                  #       that of the actual MD5 hash of the downloaded script
                  #       data.
                  #
                  set lineMd5 [lindex $fields 7]

                  if {[string length $lineMd5] == 0} then {
                    tqputs $channel [appendArgs \
                        "---- invalid md5 value for update script line: " \
                        $line \"\n]

                    continue
                  }

                  #
                  # NOTE: Next, grab the sha1 field and see if it looks valid.
                  #       Below, the value of this field will be compared to
                  #       that of the actual SHA1 hash of the downloaded script
                  #       data.
                  #
                  set lineSha1 [lindex $fields 8]

                  if {[string length $lineSha1] == 0} then {
                    tqputs $channel [appendArgs \
                        "---- invalid sha1 value for update script line: " \
                        $line \"\n]

                    continue
                  }

                  #
                  # NOTE: Next, grab the sha512 field and see if it looks
                  #       valid.  Below, the value of this field will be
                  #       compared to that of the actual SHA512 hash of the
                  #       downloaded script data.
                  #
                  set lineSha512 [lindex $fields 9]

                  if {[string length $lineSha512] == 0} then {
                    tqputs $channel [appendArgs \
                        "---- invalid sha512 value for update script line: " \
                        $line \"\n]

                    continue
                  }

                  #
                  # NOTE: Next, show the extra information associated with
                  #       this update script, if any.
                  #
                  tqputs $channel [appendArgs \
                      "---- fetching update script from \"" $baseUri "\" (" \
                      $dateTime ") with notes:\n"]

                  set trimNotes [string trim $notes]

                  tqputs $channel [appendArgs \
                      [expr {[string length $trimNotes] > 0 ? $trimNotes : \
                      "<none>"}] "\n---- end of update script notes\n"]

                  #
                  # NOTE: Next, attempt to fetch the update script data.
                  #
                  set code [catch {getUpdateScriptData $baseUri} result]

                  if {$code == 0} then {
                    #
                    # NOTE: Success, set the script data from the result.
                    #
                    set scriptData $result
                  } else {
                    #
                    # NOTE: Failure, report the error message to the log.
                    #
                    tqputs $channel [appendArgs \
                        "---- failed to fetch update script: " $result \n]

                    continue
                  }

                  #
                  # NOTE: Next, verify that the md5, sha1, and sha512
                  #       hashes of the raw script data match what was
                  #       specified in the md5, sha1, and sha512 fields.
                  #
                  set scriptMd5 [hash normal md5 $scriptData]

                  if {![string equal -nocase $lineMd5 $scriptMd5]} then {
                    tqputs $channel [appendArgs \
                        "---- wrong md5 value \"" $scriptMd5 \
                        "\" for update script line: " $line \"\n]

                    continue
                  }

                  set scriptSha1 [hash normal sha1 $scriptData]

                  if {![string equal -nocase $lineSha1 $scriptSha1]} then {
                    tqputs $channel [appendArgs \
                        "---- wrong sha1 value \"" $scriptSha1 \
                        "\" for update script line: " $line \"\n]

                    continue
                  }

                  set scriptSha512 [hash normal sha512 $scriptData]

                  if {![string equal -nocase $lineSha512 $scriptSha512]} then {
                    tqputs $channel [appendArgs \
                        "---- wrong sha512 value \"" $scriptSha512 \
                        "\" for update script line: " $line \"\n]

                    continue
                  }

                  #
                  # NOTE: Finally, everything looks good.  Therefore, just
                  #       evaluate the update script and print the result.
                  #
                  tqputs $channel [appendArgs \
                      "---- evaluating update script from \"" $baseUri \
                      \"...\n]

                  #
                  # NOTE: Reset the variables that will be used to contain
                  #       the result of the update script.
                  #
                  set code 0; set result ""

                  #
                  # NOTE: Manually override file name to be returned by
                  #       [info script] to refer back to the originally
                  #       read script base URI.
                  #
                  object invoke -flags +NonPublic Interpreter.GetActive \
                      PushScriptLocation $baseUri true

                  try {
                    #
                    # NOTE: Evaluate the update script in the context of
                    #       the caller.
                    #
                    set code [catch {uplevel 1 $scriptData} result]
                  } finally {
                    #
                    # NOTE: Reset manual override of the script file name
                    #       to be returned by [info script].
                    #
                    object invoke -flags +NonPublic Interpreter.GetActive \
                        PopScriptLocation true
                  }

                  host result $code $result; incr scriptCount
                  tqputs $channel "\n---- end of update script results\n"
                }
              } elseif {$checkBuild && $compare < 0} then {
                #
                # NOTE: The patch level from the line is less, we are more
                #       up-to-date than the latest version?
                #
                return [list [appendArgs "running build " $enginePatchLevel \
                    " is newer than the latest build " $patchLevel]]
              } else {
              } elseif {$checkBuild} then {
                #
                # NOTE: The patch levels are equal, we are up-to-date.
                #
                return [list "running build is the latest"]
              }
            }
          }
        }
      }

      #
      # NOTE: Figure out what the final result should be.  If we get
      #       to this point when checking for a new build, something
      #       must have gone awry.  Otherwise, report the number of
      #       update scripts that were successfully processed.
      #
      if {$wantScripts} then {
        if {$scriptCount > 0} then {
          return [list [appendArgs \
              "processed " $scriptCount " update scripts"]]
        } else {
          return [list "no update scripts were processed"]
        }
      } else {
      return [list "cannot determine if running build is the latest"]
        return [list "cannot determine if running build is the latest"]
      }
    }

    proc getReturnType { object member } {
      if {[string length $object] == 0 || [string length $member] == 0} then {
        return ""
      }

1413
1414
1415
1416
1417
1418
1419











1420
1421
1422
1423
1424
1425
1426
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673







+
+
+
+
+
+
+
+
+
+
+








      if {[string length $type] == 0} then {
        return ""
      }

      return [expr {[$type IsValueType] ? 0 : "null"}]
    }

    proc getHostSize {} {
      #
      # NOTE: Attempt to query the size from the host; failing that,
      #       return a reasonable default value.
      #
      if {[catch {host size} result] == 0} then {
        return $result
      }
      return [list 80 25]; # TODO: Good default?
    }

    proc parray { a args } {
      if {[llength $args] > 2} then {
        error "wrong # args: should be \"parray a ?pattern?\""
      }

      upvar 1 $a array
1437
1438
1439
1440
1441
1442
1443
1444

1445
1446
1447
1448
1449
1450
1451
1684
1685
1686
1687
1688
1689
1690

1691
1692
1693
1694
1695
1696
1697
1698







-
+








        if {$length > $maxLength} {
          set maxLength $length
        }
      }

      set maxLength [expr {$maxLength + [string length $a] + 2}]
      set hostLength [lindex [host size] 0]
      set hostLength [lindex [getHostSize] 0]
      set valueLength [expr {$hostLength - $maxLength - 5}]; # " ... "

      foreach name $names {
        #
        # NOTE: Format the array element name for display.
        #
        set nameString [appendArgs $a ( $name )]
1485
1486
1487
1488
1489
1490
1491
1492

1493
1494
1495
1496
1497
1498
1499
1732
1733
1734
1735
1736
1737
1738

1739
1740
1741
1742
1743
1744
1745
1746







-
+







        set length [string length $name]

        if {$length > $maxLength} {
          set maxLength $length
        }
      }

      set hostLength [lindex [host size] 0]
      set hostLength [lindex [getHostSize] 0]
      set valueLength [expr {$hostLength - $maxLength - 5}]; # " ... "

      foreach {name value} $d {
        #
        # NOTE: If the value by itself is too long to fit on one host line,
        #       just truncate and ellipsis it.
        #
Changes to Externals/Eagle/lib/Eagle1.0/test.eagle.
76
77
78
79
80
81
82
83
84


85
86
87
88
89
90
91
76
77
78
79
80
81
82


83
84
85
86
87
88
89
90
91







-
-
+
+







      if {[string length $string] > 0} then {
        appendSharedLogFile $fileName $string
      }
    }
  }

  proc getSoftwareRegistryKey { wow64 } {
    if {$wow64 && [info exists ::tcl_platform(machine)] && \
        $::tcl_platform(machine) eq "amd64"} then {
    if {$wow64 && [info exists ::tcl_platform(machine)] && [lsearch -exact \
        [list ia64 amd64] $::tcl_platform(machine)] != -1} then {
      #
      # NOTE: Return the WoW64 registry key name because we are running on a
      #       64-bit operating system and the caller specifically requested
      #       the WoW64 registry key name.
      #
      return Software\\Wow6432Node
    } else {
835
836
837
838
839
840
841






842

843
844


845
846
847
848
849
850
851
835
836
837
838
839
840
841
842
843
844
845
846
847

848
849

850
851
852
853
854
855
856
857
858







+
+
+
+
+
+
-
+

-
+
+








    if {[llength $options] > 0} then {eval lappend command $options}

    lappend command -- $commandName

    if {[llength $args] > 0} then {eval lappend command $args}

    if {[info exists ::no(exec)]} then {
      tputs $::test_channel [appendArgs "---- skipping command: " $command \n]

      set procName [lindex [info level [info level]] 0]
      error "test use of \[$procName\] has been disabled"
    } else {
    tputs $::test_channel [appendArgs "---- running command: " $command \n]
      tputs $::test_channel [appendArgs "---- running command: " $command \n]

    return [uplevel 1 $command]
      return [uplevel 1 $command]
    }
  }

  proc testClrExec { commandName options args } {
    set command [list exec]

    if {[llength $options] > 0} then {eval lappend command $options}

859
860
861
862
863
864
865






866

867
868


869
870
871

872
873









874
875

876
877


878
879
880
881
882
883
884
866
867
868
869
870
871
872
873
874
875
876
877
878

879
880

881
882
883
884
885
886


887
888
889
890
891
892
893
894
895


896
897

898
899
900
901
902
903
904
905
906







+
+
+
+
+
+
-
+

-
+
+



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

-
+
+







          [appendArgs \" [file nativename $commandName] \"]
    } else {
      lappend command $commandName
    }

    if {[llength $args] > 0} then {eval lappend command $args}

    if {[info exists ::no(exec)]} then {
      tputs $::test_channel [appendArgs "---- skipping command: " $command \n]

      set procName [lindex [info level [info level]] 0]
      error "test use of \[$procName\] has been disabled"
    } else {
    tputs $::test_channel [appendArgs "---- running command: " $command \n]
      tputs $::test_channel [appendArgs "---- running command: " $command \n]

    return [uplevel 1 $command]
      return [uplevel 1 $command]
    }
  }

  proc execTestShell { options args } {
    if {[info exists ::no(exec)]} then {
    tputs $::test_channel [appendArgs \
        "---- running nested shell: exec " \
      tputs $::test_channel [appendArgs \
          "---- skipping nested shell: exec " [string trim [appendArgs \
          $options " " -- " \"" [info nameofexecutable] "\" " $args]] \n]

      set procName [lindex [info level [info level]] 0]
      error "test use of \[$procName\] has been disabled"
    } else {
      tputs $::test_channel [appendArgs \
          "---- running nested shell: exec " [string trim [appendArgs \
        [string trim [appendArgs $options " " -- " \"" \
        [info nameofexecutable] "\" " $args]] \n]
          $options " " -- " \"" [info nameofexecutable] "\" " $args]] \n]

    return [uplevel 1 execShell [list $options] $args]
      return [uplevel 1 execShell [list $options] $args]
    }
  }

  proc isRandomOrder {} {
    return [expr {[info exists ::test_random_order] && \
                  [string is boolean -strict $::test_random_order] && \
                  $::test_random_order}]
  }
1316
1317
1318
1319
1320
1321
1322
1323

1324
1325
1326
1327
1328
1329
1330
1331


1332
1333
1334
1335
1336
1337
1338
1338
1339
1340
1341
1342
1343
1344

1345
1346
1347
1348
1349
1350
1351


1352
1353
1354
1355
1356
1357
1358
1359
1360







-
+






-
-
+
+







        lappend result $fileName
      }
    }

    return $result
  }

  proc formatDecimal { value {places 4} } {
  proc formatDecimal { value {places 4} {zeros false} } {
    if {[isEagle] && [llength [info commands object]] > 0} then {
      #
      # HACK: This works; however, in order to do this kind of thing cleanly,
      #       we really need the Tcl [format] command.
      #
      set result [object invoke String Format [appendArgs "{0:0." \
          [string repeat # $places] "}"] [set object [object invoke \
          -create Double Parse $value]]]
          [string repeat [expr {$zeros ? "0" : "#"}] $places] "}"] \
          [set object [object invoke -create Double Parse $value]]]

      unset object; # dispose
    } else {
      #
      # NOTE: See, nice and clean when done in Tcl?
      #
      set result [format [appendArgs %. $places f] $value]
2161
2162
2163
2164
2165
2166
2167






2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181

2182
2183
2184
2185
2186
2187
2188
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208

2209
2210
2211
2212
2213
2214
2215
2216







+
+
+
+
+
+













-
+







          # NOTE: Delete the temporary file we used to query the machine
          #       type for the native Tcl shell.
          #
          catch {file delete $fileName}
        }
      }
    }

    proc getTclVersionForTclShell {} {
      return [testExecTclScript {
        puts -nonewline stdout [info tclversion]
      }]
    }

    proc getCommandsForTclShell {} {
      return [testExecTclScript {
        puts -nonewline stdout [info commands]
      }]
    }

    proc getMachineForTclShell {} {
      return [testExecTclScript {
        puts -nonewline stdout $tcl_platform(machine)
      }]
    }

    proc getTkVersion {} {
    proc getTkVersionForTclShell {} {
      return [testExecTclScript {
        puts -nonewline stdout [package require Tk]; exit
      }]
    }

    proc getGarudaDll {} {
      #
2261
2262
2263
2264
2265
2266
2267





















2268
2269
2270
2271
2272
2273


2274


2275
2276

2277
2278
2279
2280
2281
2282




2283
2284
2285
2286
2287
2288
2289
2290




2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301



2302
2303
2304
2305
2306
2307
2308
2309
2310
2311



2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323


2324


2325
2326

2327
2328
2329
2330
2331
2332
2333




2334
2335
2336
2337
2338
2339
2340
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321

2322
2323
2324
2325
2326
2327

2328
2329
2330
2331
2332
2333

2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344

2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371

2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385

2386
2387
2388
2389
2390
2391

2392
2393
2394
2395
2396
2397
2398

2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409







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





-
+
+

+
+

-
+





-
+
+
+
+







-
+
+
+
+











+
+
+









-
+
+
+











-
+
+

+
+

-
+






-
+
+
+
+








      object unimport -importpattern System.Windows.Forms.Design
      object unimport -importpattern System.Windows.Forms.Layout
      object unimport -importpattern System.Windows.Forms.PropertyGridInternal
      object unimport -importpattern System.Windows.Forms.VisualStyles
    }

    proc getTestLibraryDirectory {} {
      #
      # NOTE: First, query the location of the script library.
      #
      set result [info library]

      #
      # NOTE: Next, If the script library is embedded within the core
      #       library itself (i.e. the script library location refers
      #       to a file, not a directory), strip off the file name.
      #
      if {[file exists $result] && [file isfile $result]} then {
        set result [file dirname $result]
      }

      #
      # NOTE: Finally, return the resulting script library directory.
      #
      return $result
    }

    #
    # NOTE: Setup the test path relative to the library path.
    #
    if {![interp issafe] && ![info exists ::test_path]} then {
      #
      # NOTE: Try the source release directory structure.
      # NOTE: Try the source release directory structure.  For this case,
      #       the final test path would be:
      #
      #           $library/../../Library/Tests
      #
      set ::test_path [file join [file normalize [file dirname \
          [file dirname [info library]]]] Library Tests]
          [file dirname [getTestLibraryDirectory]]]] Library Tests]

      if {![file exists $::test_path] || \
          ![file isdirectory $::test_path]} then {
        #
        # NOTE: Try the source release directory structure again; this time,
        #       assume only the embedded script library was used.
        #       assume only the embedded script library was used.  For this
        #       case, the final test path would be:
        #
        #           $base/Library/Tests
        #
        set ::test_path [file join [info base] Library Tests]
      }

      if {![file exists $::test_path] || \
          ![file isdirectory $::test_path]} then {
        #
        # NOTE: Try for the test package directory.
        # NOTE: Try for the test package directory.  For this case, the final
        #       test path would be:
        #
        #           $script/../Test1.0
        #
        set ::test_path [file join [file normalize [file dirname \
            [file dirname [info script]]]] [appendArgs Test \
            [info engine Version]]]
      }

      if {![file exists $::test_path] || \
          ![file isdirectory $::test_path]} then {
        #
        # NOTE: Try for the test package directory again; this time, use the
        #       base path and assume the source release directory structure.
        #       For this case, the final test path would be:
        #
        #           $base/lib/Test1.0
        #
        set ::test_path [file join [info base] lib [appendArgs Test \
            [info engine Version]]]
      }

      if {![file exists $::test_path] || \
          ![file isdirectory $::test_path]} then {
        #
        # NOTE: Try for the test package directory again; this time, use the
        #       base path.
        #       base path.  For this case, the final test path would be:
        #
        #           $base/Test1.0
        #
        set ::test_path [file join [info base] [appendArgs Test \
            [info engine Version]]]
      }

      if {![file exists $::test_path] || \
          ![file isdirectory $::test_path]} then {
        #
        # NOTE: This must be a binary release, no "Library" directory then.
        #       Also, binary releases have an upper-case "Tests" directory
        #       name that originates from the "update.bat" tool.  This must
        #       match the casing used in "update.bat".
        #       match the casing used in "update.bat".  For this case, the
        #       final test path would be:
        #
        #           $library/../../Tests
        #
        set ::test_path [file join [file normalize [file dirname \
            [file dirname [info library]]]] Tests]
            [file dirname [getTestLibraryDirectory]]]] Tests]
      }

      if {![file exists $::test_path] || \
          ![file isdirectory $::test_path]} then {
        #
        # NOTE: Fallback to using the base directory and checking for a
        #       "Tests" directory beneath it.
        #       "Tests" directory beneath it.  For this case, the final
        #       test path would be:
        #
        #           $base/Tests
        #
        set ::test_path [file join [info base] Tests]
      }
    }

    #
    # NOTE: Fake having the tcltest package unless we are prevented.
Changes to Externals/Eagle/lib/Eagle1.0/vendor.eagle.
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194







-
+







    #
    # NOTE: Check for any overridden settings that may have been specified via
    #       the command line, etc.
    #
    checkForTestOverrides stdout [expr {[info exists test_overrides] ? \
        $test_overrides : [list binary_directory build_base_directory \
        build_directory common_directory connection_flags database_directory \
        datetime_format scratch_directory temporary_directory \
        datetime_format release_version scratch_directory temporary_directory \
        test_configuration test_configurations test_constraints \
        test_machine test_overrides test_platform test_suite test_year \
        test_years test_year_clr_v2 test_year_clr_v4 vendor_directory]}] false

    #
    # NOTE: Set the name of the running test suite, if necessary.
    #
Changes to Externals/Eagle/lib/Test1.0/constraints.eagle.
26
27
28
29
30
31
32








































































































33
34
35
36
37
38
39
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143







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







    #       versions of Mono supported by the test suite infrastructure.
    #
    return [list \
        [list 2 0] [list 2 2] [list 2 4] [list 2 6] [list 2 8] [list 2 10] \
        [list 2 11] [list 2 12] [list 3 0] [list 3 1] [list 3 2] [list 3 3] \
        [list 3 4] [list 3 5] [list 3 6]]
  }

  proc checkForTestSuiteFiles { channel } {
    tputs $channel "---- checking for test suite files... "

    #
    # NOTE: Start out with no test suite files to check.
    #
    set fileNames [list]

    #
    # NOTE: Check if the base package path is available.
    #
    if {[info exists ::test_package_path]} then {
      #
      # TODO: If additional test suite files are added within the base
      #       package path, add them here as well.
      #
      foreach fileNameOnly [list \
          embed.eagle init.eagle pkgIndex.eagle pkgIndex.tcl \
          safe.eagle shell.eagle test.eagle vendor.eagle word.tcl] {
        #
        # NOTE: First, check if the file resides in the Eagle-specific
        #       package sub-directory.  Failing that, fallback to using
        #       the base package path itself.
        #
        set fileName [file join \
            $::test_package_path Eagle1.0 $fileNameOnly]

        if {![file exists $fileName]} then {
          set fileName [file join $::test_package_path $fileNameOnly]
        }

        #
        # NOTE: If the test suite file exists, add it to the list of file
        #       names to process.
        #
        if {[file exists $fileName]} then {
          lappend fileNames $fileName
        }
      }
    }

    #
    # NOTE: Check if the test package path is available.
    #
    if {[info exists ::test_path]} then {
      #
      # TODO: If additional test suite files are added within the test
      #       package path, add them here as well.
      #
      foreach fileNameOnly [list \
          all.eagle constraints.eagle epilogue.eagle pkgIndex.eagle \
          pkgIndex.tcl prologue.eagle] {
        #
        # NOTE: Check if the file resides in the test package directory.
        #
        set fileName [file join $::test_path $fileNameOnly]

        #
        # NOTE: If the test suite file exists, add it to the list of file
        #       names to process.
        #
        if {[file exists $fileName]} then {
          lappend fileNames $fileName
        }
      }
    }

    #
    # NOTE: Did we find any test suite files?
    #
    if {[llength $fileNames] > 0} then {
      #
      # NOTE: Eagle has a built-in hashing command; however, Tcl requires
      #       a package.  Make sure we can hash content before proceeding.
      #
      if {[isEagle] || [catch {package require sha1}] == 0} then {
        tputs $channel yes\n

        foreach fileName $fileNames {
          if {[isEagle]} then {
            set sha1 [hash normal sha1 [readFile $fileName]]
          } else {
            #
            # BUGBUG: Apparently, the ActiveState tcllib sha1 package may
            #         have a bug that produces the wrong values here.  No
            #         attempt is made here to work around any such bug.
            #
            set sha1 [sha1::sha1 -hex -filename $fileName]
          }

          tputs $channel [appendArgs \
              "---- file \"" $fileName "\"... sha1 (" $sha1 ")\n"]
        }

        #
        # NOTE: We are done here, return now.
        #
        return
      }
    }

    tputs $channel no\n
  }

  proc checkForPlatform { channel } {
    tputs $channel "---- checking for platform... "

    if {[info exists ::tcl_platform(platform)]} then {
      addConstraint $::tcl_platform(platform)

205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323







-
+







      }
    }

    tputs $channel no\n
  }

  proc checkForTclOptions { channel } {
    tputs $channel "---- checking for Tcl options..."
    tputs $channel "---- checking for Tcl options... "

    if {![isEagle]} then {
      set result [list]

      #
      # NOTE: This test constraint is needed by test "benchmark-1.22".
      #
649
650
651
652
653
654
655












656
657
658
659
660
661
662
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778







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







      addConstraint [appendArgs command. $name]

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForTestExec { channel } {
    tputs $channel "---- checking for test use of \"exec\" command... "

    if {![info exists ::no(testExec)]} then {
      addConstraint testExec

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForTestMachine { channel } {
    tputs $channel "---- checking for test machine... "

    if {[info exists ::test_machine] && \
        [string length $::test_machine] > 0} then {
      addConstraint [appendArgs machine. $::test_machine]
950
951
952
953
954
955
956
957

958
959

960

961
962
963
964
965
966
967

968
969
970

971
972
973
974
975
976
977
1066
1067
1068
1069
1070
1071
1072

1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083

1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
1094







-
+


+
-
+






-
+


-
+







    } else {
      tputs $channel no\n
    }
  }

  proc checkForTiming {
          channel threshold {constraint ""} {tries 1} {delay 1000}
          {asynchronous false} } {
          {average false} {asynchronous false} } {
    tputs $channel [appendArgs \
        "---- checking for precision timing (threshold of " $threshold \
        " milliseconds" [expr {$average ? " average" : ""}] ", delay of " \
        " milliseconds, delay of " $delay " milliseconds)... "]
        $delay " milliseconds)... "]

    #
    # HACK: Sometimes the first try takes quite a bit longer than subsequent
    #       tries.  We attempt to bypass this problem by retrying a set number
    #       of times (which can be overridden by the caller) before giving up.
    #
    set try 0
    set total 0
    set difference unknown

    for {} {$try < $tries} {incr try} {
    for {set try 0} {$try < $tries} {incr try} {
      #
      # NOTE: Create a script that will set the final clicks value.  This must
      #       use a global variable due to the nature of [after].
      #
      set stopScript {
        set ::stopClicks [expr {[clock clicks -milliseconds] & 0x7fffffff}]
      }
996
997
998
999
1000
1001
1002













1003
1004
1005
1006
1007
1008
1009
1010

1011
1012
1013

1014
1015


1016
1017
1018





1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029




1030
1031
1032
1033
1034
1035
1036
1113
1114
1115
1116
1117
1118
1119
1120
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







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







-
+
-
-
-
+


+
+
-
-
-
+
+
+
+
+








-
-
-
+
+
+
+








      #
      # NOTE: Calculate the difference between the actual and expected
      #       number of milliseconds.
      #
      set difference [expr {abs($stop - $start - $delay)}]

      #
      # NOTE: Keep track of the total number of milliseconds elapsed for
      #       all iterations of this loop.
      #
      incr total $difference

      #
      # NOTE: If we are using the average difference, handle that now.
      #
      if {$average && $tries > 1} then {
        set difference [expr {$total / $tries}]
      }

      #
      # NOTE: Are we within the threshold specified by the caller?
      #
      if {$difference >= 0 && $difference <= $threshold} then {
        #
        # NOTE: We appear to be capable of fairly precise timing.
        #
        if {[string length $constraint] > 0} then {
        if {[string length $constraint] == 0} then {
          addConstraint $constraint
        } else {
          addConstraint timing
          set constraint timing
        }

        addConstraint $constraint

        tputs $channel [appendArgs "yes (0 <= " $difference " <= " \
            $threshold " milliseconds, tried " [expr {$try + 1}] \
            " " [expr {$try + 1 > 1 ? "times" : "time"}] ")\n"]
        tputs $channel [appendArgs \
            "yes (0 <= " $difference " <= " $threshold " milliseconds" \
            [expr {$average ? " average" : ""}] ", tried " [expr {$try + 1}] \
            " out of " $tries " " [expr {$tries > 1 ? "times" : "time"}] \
            ", \"" $constraint "\")\n"]

        #
        # NOTE: We are done here, return now.
        #
        return
      }
    }

    tputs $channel [appendArgs "no (0 <= " $difference " > " \
        $threshold " milliseconds, tried " $try " " \
        [expr {$try > 1 ? "times" : "time"}] ")\n"]
    tputs $channel [appendArgs \
        "no (0 <= " $difference " > " $threshold " milliseconds" \
        [expr {$average ? " average" : ""}] ", tried " $try " out of " \
        $tries " " [expr {$tries > 1 ? "times" : "time"}] ")\n"]
  }

  proc checkForPerformance { channel } {
    tputs $channel "---- checking for performance testing... "

    #
    # NOTE: Are we allowed to do performance testing?
1047
1048
1049
1050
1051
1052
1053











1054

1055
1056









1057
1058
1059
1060
1061
1062
1063
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197

1198
1199

1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215







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

-
+
+
+
+
+
+
+
+
+







  proc checkForStackIntensive { channel } {
    tputs $channel "---- checking for stack intensive testing... "

    #
    # NOTE: Are we allowed to do stack intensive testing?
    #
    if {![info exists ::no(stackIntensive)]} then {
      if {[isEagle]} then {
        #
        # NOTE: Attempt to query for native stack checking in Eagle.
        #
        if {[catch {object invoke -flags +NonPublic \
                Eagle._Components.Private.NativeStack CanQueryThread} \
                canQueryThread] == 0 && \
            $canQueryThread} then {
          #
          # NOTE: Yes, it appears that it is available.
          #
      addConstraint stackIntensive
          addConstraint stackIntensive

      tputs $channel yes\n
          tputs $channel yes\n
        } else {
          tputs $channel no\n
        }
      } else {
        addConstraint stackIntensive

        tputs $channel yes\n
      }
    } else {
      tputs $channel no\n
    }
  }

  proc checkForInteractive { channel } {
    tputs $channel "---- checking for interactive user... "
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
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287









1288
1289
1290
1291
1292
1293
1294
1295
1296
1297








1298
1299
1300
1301
1302
1303
1304
1305
1306



1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319







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

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

-
-
-
+
+
+
+
+
+








  proc checkForNetwork { channel host timeout } {
    tputs $channel [appendArgs \
        "---- checking for network connectivity to host \"" $host "\"... "]

    if {[isEagle]} then {
      #
      # NOTE: Running this check on the Mono 3.3.0 release build will lock
      #       up the process; therefore, attempt to skip it in that case.
      #
      if {![isMono] || ![haveConstraint mono33]} then {
        #
      # BUGBUG: Tcl 8.4 does not like this expression (and Tcl tries to
      #         compile it even though it will only actually ever be
      #         evaluated in Eagle).
      #
      set expr {[llength [info commands uri]] > 0 && \
          [catch {uri ping $host $timeout} response] == 0 && \
          [lindex $response 0] in [list Success TimedOut] && \
          [string is integer -strict [lindex $response 1]] && \
          [lindex $response 1] <= $timeout}
        # BUGBUG: Tcl 8.4 does not like this expression (and Tcl tries to
        #         compile it even though it will only actually ever be
        #         evaluated in Eagle).
        #
        set expr {[llength [info commands uri]] > 0 && \
            [catch {uri ping $host $timeout} response] == 0 && \
            [lindex $response 0] in [list Success TimedOut] && \
            [string is integer -strict [lindex $response 1]] && \
            [lindex $response 1] <= $timeout}

      #
      # NOTE: Does it look like we are able to contact the network host?
      #
      if {[expr $expr]} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        addConstraint [appendArgs network_ $host]
        #
        # NOTE: Does it look like we are able to contact the network host?
        #
        if {[expr $expr]} then {
          #
          # NOTE: Yes, it appears that it is available.
          #
          addConstraint [appendArgs network_ $host]

        tputs $channel [appendArgs "yes (" $response ")\n"]
      } else {
        tputs $channel no\n
          tputs $channel [appendArgs "yes (" $response ")\n"]
        } else {
          tputs $channel no\n
        }
      } else {
        tputs $channel "skipped, broken on Mono 3.3.0\n"
      }
    } else {
      #
      # HACK: Running in Tcl, just assume we have network access.
      #
      addConstraint [appendArgs network_ $host]

1356
1357
1358
1359
1360
1361
1362












1363
1364
1365
1366
1367
1368
1369
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541







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








        tputs $channel [appendArgs "yes (" \
            [object invoke $certificate Subject] ")\n"]
      } else {
        tputs $channel no\n
      }
    }

    proc checkForCompileCSharp { channel } {
      tputs $channel "---- checking for test use of C# compiler... "

      if {![info exists ::no(compileCSharp)]} then {
        addConstraint compileCSharp

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForAdministrator { channel } {
      tputs $channel "---- checking for administrator... "

      if {[isAdministrator]} then {
        addConstraint administrator; # running as full admin.

1665
1666
1667
1668
1669
1670
1671
1672

1673
1674
1675
1676
1677
1678

1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690


1691
1692
1693
1694
1695
1696
1697
1837
1838
1839
1840
1841
1842
1843

1844
1845
1846
1847
1848
1849

1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860


1861
1862
1863
1864
1865
1866
1867
1868
1869







-
+





-
+










-
-
+
+







          "-bit " $machine "\"... "]

      #
      # NOTE: What are the machine architecture and the
      #       number of bits for this operating system?
      #
      if {[info exists ::tcl_platform(machine)] && \
          [info exists ::tcl_platform(osBits)]} then {
          [info exists ::tcl_platform(processBits)]} then {
        #
        # NOTE: Does the machine and number of bits match
        #       what the caller specified?
        #
        if {$::tcl_platform(machine) eq $machine && \
            $::tcl_platform(osBits) eq $bits} then {
            $::tcl_platform(processBits) eq $bits} then {
          #
          # NOTE: Yes, it matches.
          #
          addConstraint [appendArgs $machine . $bits bit]

          set result yes
        } else {
          set result no
        }

        tputs $channel [appendArgs $result ", " $::tcl_platform(osBits) -bit \
            " " $::tcl_platform(machine) \n]
        tputs $channel [appendArgs $result ", " $::tcl_platform(processBits) \
            -bit " " $::tcl_platform(machine) \n]
      } else {
        tputs $channel "no, unknown\n"
      }
    }

    proc checkForGarudaDll { channel } {
      #
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051



2052


2053

2054
2055
2056
2057
2058
2059




2060
2061


2062
2063

2064
2065
2066
2067
2068
2069
2070
2071
2072
2073


2074

2075
2076
2077
2078
2079
2080
2081

2082
2083
2084

2085
2086
2087
2088
2089
2090
2091
2213
2214
2215
2216
2217
2218
2219




2220
2221
2222
2223
2224
2225

2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236


2237
2238
2239

2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252

2253
2254
2255
2256
2257
2258
2259

2260

2261

2262
2263
2264
2265
2266
2267
2268
2269







-
-
-
-
+
+
+

+
+
-
+






+
+
+
+
-
-
+
+

-
+










+
+
-
+






-
+
-

-
+







      } else {
        tputs $channel no\n
      }
    }

    proc checkForTclShell { channel } {
      #
      # HACK: We do not care about the machine type returned from this
      #       procedure, we only care if it returns "error" because that
      #       would indicate an error was caught during [exec] (i.e. the
      #       native Tcl shell could not be executed).
      # HACK: If this returns "error" that normally indicates an error was
      #       caught during [exec] (i.e. the native Tcl shell could not be
      #       executed).
      #
      set prefix "---- checking for Tcl shell version... "

      if {[catch {getMachineForTclShell} result] == 0 && \
      if {[catch {getTclVersionForTclShell} result] == 0 && \
          $result ne "error"} then {
        #
        # NOTE: Yes, a native Tcl shell appears to be available.
        #
        addConstraint tclShell

        #
        # NOTE: Now, add the version specific test constraint.
        #
        addConstraint [appendArgs tclShell [string map [list . ""] $result]]
        tputs $channel [appendArgs "---- checking for Tcl shell... yes (" \
            $result ")\n"]

        tputs $channel [appendArgs $prefix "yes (" $result ")\n"]
      } else {
        tputs $channel "---- checking for Tcl shell... no\n"
        tputs $channel [appendArgs $prefix no\n]
      }
    }

    proc checkForTkPackage { channel } {
      #
      # HACK: We do not care about the Tk version returned from this
      #       procedure, we only care if it returns "error" because that
      #       would indicate an error was caught during [exec] (i.e. the
      #       native Tcl shell could not be executed).
      #
      set prefix "---- checking for Tk package version... "

      if {[catch {getTkVersion} result] == 0 && \
      if {[catch {getTkVersionForTclShell} result] == 0 && \
          $result ne "error"} then {
        #
        # NOTE: Yes, a native Tk package appears to be available.
        #
        addConstraint tkPackage

        tputs $channel [appendArgs "---- checking for Tk package... yes (" \
        tputs $channel [appendArgs $prefix "yes (" $result ")\n"]
            $result ")\n"]
      } else {
        tputs $channel "---- checking for Tk package... no\n"
        tputs $channel [appendArgs $prefix no\n]
      }
    }

    proc checkForPowerShell { channel } {
      tputs $channel "---- checking for PowerShell... "

      #
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573










2574
2575
2576
2577
2578
2579
2580
2736
2737
2738
2739
2740
2741
2742









2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759







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







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

    #
    # NOTE: We need several of our test constraint related commands in the
    #       global namespace.
    #
    exportAndImportPackageCommands [namespace current] [list \
        getKnownMonoVersions checkForPlatform checkForWindowsVersion \
        checkForScriptLibrary checkForVariable checkForTclOptions \
        checkForWindowsCommandProcessor checkForFossil checkForEagle \
        checkForSymbols checkForLogFile checkForGaruda checkForShell \
        checkForDebug checkForTk checkForVersion checkForCommand \
        checkForTestMachine checkForTestPlatform checkForTestConfiguration \
        checkForTestSuffix checkForFile checkForPathFile checkForNativeCode \
        checkForTip127 checkForTip194 checkForTip241 checkForTip285 \
        checkForTip405 checkForTip426 checkForTiming checkForPerformance \
        getKnownMonoVersions checkForTestSuiteFiles checkForPlatform \
        checkForWindowsVersion checkForScriptLibrary checkForVariable \
        checkForTclOptions checkForWindowsCommandProcessor checkForFossil \
        checkForEagle checkForSymbols checkForLogFile checkForGaruda \
        checkForShell checkForDebug checkForTk checkForVersion \
        checkForCommand checkForTestExec checkForTestMachine \
        checkForTestPlatform checkForTestConfiguration checkForTestSuffix \
        checkForFile checkForPathFile checkForNativeCode checkForTip127 \
        checkForTip194 checkForTip241 checkForTip285 checkForTip405 \
        checkForTip426 checkForTiming checkForPerformance \
        checkForStackIntensive checkForInteractive checkForInteractiveCommand \
        checkForUserInteraction checkForNetwork checkForCompileOption] false \
        false

    ###########################################################################
    ############################## END Tcl ONLY ###############################
    ###########################################################################
Changes to Externals/Eagle/lib/Test1.0/epilogue.eagle.
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141







-
+









-
+








    #
    # NOTE: Show the current state of the memory.
    #
    catch {debug memory} memory

    tputs $test_channel [appendArgs "---- ending memory: " \
        [formatListAsDict $memory] \n]
        [formatListAsDict $memory <none>] \n]

    unset memory

    #
    # NOTE: Show the current state of the native stack.
    #
    catch {debug stack true} stack

    tputs $test_channel [appendArgs "---- ending stack: " \
        [formatListAsDict $stack] \n]
        [formatListAsDict $stack <none>] \n]

    unset stack

    #
    # NOTE: Check for and display any duplicate test names that we found.  In
    #       theory, this checking may produce false positives if a test file
    #       (or the entire test suite) is run multiple times without resetting
Changes to Externals/Eagle/lib/Test1.0/prologue.eagle.
87
88
89
90
91
92
93
94


95
96
97
98
99
100
101
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102







-
+
+







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

  #
  # NOTE: Set the local root directory of the source checkout (i.e. of Eagle
  #       or whatever project the Eagle binaries are being used by) using a
  #       Fossil binary in the PATH, if available.
  #
  if {![info exists root_path] && ![info exists no(fossil)]} then {
  if {![info exists root_path] && \
      ![info exists no(exec)] && ![info exists no(fossil)]} then {
    set pattern {^local-root:\s+(.*?)\s+$}

    if {[catch {set exec [exec -- fossil info]}] || \
        [regexp -line -- $pattern $exec dummy directory] == 0} then {
      #
      # NOTE: We could not query local root directory of the source checkout
      #       from Fossil; therefore, attempt to make an educated guess.  This
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
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







-
+





-
+





-
+





-
+







    tputs $test_channel [appendArgs "---- output encoding: " \
        $encoding \n]

    unset encoding
    catch {host query} host

    tputs $test_channel [appendArgs "---- host query: " \
        [formatListAsDict $host] \n]
        [formatListAsDict $host <none>] \n]

    unset host
    catch {debug memory} memory

    tputs $test_channel [appendArgs "---- starting memory: " \
        [formatListAsDict $memory] \n]
        [formatListAsDict $memory <none>] \n]

    unset memory
    catch {debug stack true} stack

    tputs $test_channel [appendArgs "---- starting stack: " \
        [formatListAsDict $stack] \n]
        [formatListAsDict $stack <none>] \n]

    unset stack
    catch {file drive} drive

    tputs $test_channel [appendArgs "---- system drive: " \
        [formatListAsDict $drive] \n]
        [formatListAsDict $drive <none>] \n]

    unset drive
  }

  tputs $test_channel [appendArgs "---- executable: \"" \
      $bin_file \"\n]

798
799
800
801
802
803
804


805
806
807
808
809
810
811
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814







+
+







    }

    #
    # NOTE: Has machine detection support been disabled?
    #
    if {![info exists no(machine)]} then {
      checkForMachine $test_channel 32 intel; # (i.e. x86)
      checkForMachine $test_channel 32 arm;   # (i.e. arm)
      checkForMachine $test_channel 64 ia64;  # (i.e. ia64)
      checkForMachine $test_channel 64 amd64; # (i.e. x64)
    }

    #
    # NOTE: Has culture detection support been disabled?
    #
    if {![info exists no(culture)]} then {
948
949
950
951
952
953
954







955
956
957
958
959
960
961
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971







+
+
+
+
+
+
+







      #
      # NOTE: For tests "excel-*", "object-2.*", "object-7.1", "object-8.*",
      #       and "object-98.*".
      #
      checkForReferenceCountTracking $test_channel
    }

    #
    # NOTE: Has testing using the C# compiler been disabled?
    #
    if {![info exists no(checkForCompileCSharp)]} then {
      checkForCompileCSharp $test_channel
    }

    #
    # NOTE: Has compile/runtime option testing support been disabled?
    #
    if {![info exists no(compileOptions)]} then {
      #
      # NOTE: Has callback queue support been enabled (at compile-time)?
      #
1070
1071
1072
1073
1074
1075
1076
1077

1078
1079
1080










1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097

1098
1099
1100
1101
1102
1103
1104
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116

1117
1118
1119
1120
1121
1122
1123
1124







-
+



+
+
+
+
+
+
+
+
+
+
















-
+







      }

      #
      # NOTE: Has Windows support been enabled (at compile-time)?
      #
      if {![info exists no(compileWindows)]} then {
        #
        # NOTE: For test "garuda-1.1".
        # NOTE: For tests "garuda-1.1" and "garuda-1.2".
        #
        checkForCompileOption $test_channel WINDOWS
      }

      #
      # NOTE: Has Windows Forms support been enabled (at compile-time)?
      #
      if {![info exists no(compileWinForms)]} then {
        #
        # NOTE: For tests "object-10.21", "tclLoad-1.2", "winForms-*.*".
        #
        checkForCompileOption $test_channel WINFORMS
      }

      #
      # NOTE: Has native code support been enabled (at compile-time)?
      #
      if {![info exists no(compileNative)]} then {
        #
        # NOTE: For tests "debug-3.2", "expr-3.2", and "host-1.1".
        #
        checkForCompileOption $test_channel NATIVE
      }

      #
      # NOTE: Has native package support been enabled (at compile-time)?
      #
      if {![info exists no(compileNativePackage)]} then {
        #
        # NOTE: For test "garuda-1.1".
        # NOTE: For tests "garuda-1.1" and "garuda-1.2".
        #
        checkForCompileOption $test_channel NATIVE_PACKAGE
      }

      #
      # NOTE: Has network support been enabled (at compile-time)?
      #
1606
1607
1608
1609
1610
1611
1612















1613
1614
1615
1616
1617
1618
1619
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654







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







        # NOTE: For test "object-2.8".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default+Disposable \
            *ToString* Eagle._Tests.Default.Disposable.ToString
      }
    }

    #
    # NOTE: Has MSBuild testing support been disabled?
    #
    if {![info exists no(msBuild)]} then {
      #
      # NOTE: For test "object-4.13".
      #
      checkForAssembly $test_channel Microsoft.Build.Framework

      #
      # NOTE: For test "object-6.1".
      #
      checkForAssembly $test_channel Microsoft.Build.Engine
    }

    #
    # NOTE: Has Excel testing support been disabled?
    #
    if {![info exists no(excel)]} then {
      #
      # NOTE: For tests "excel-*.*".
      #
1778
1779
1780
1781
1782
1783
1784
1785

1786
1787
1788
1789
1790
1791
1792
1813
1814
1815
1816
1817
1818
1819

1820
1821
1822
1823
1824
1825
1826
1827







-
+







    }

    #
    # NOTE: Has Garuda testing support been disabled?
    #
    if {![info exists no(garudaDll)]} then {
      #
      # NOTE: For test "garuda-1.1".
      # NOTE: For tests "garuda-1.1" and "garuda-1.2".
      #
      checkForGarudaDll $test_channel
    }

    ###########################################################################
    ########################## END Eagle Constraints ##########################
    ###########################################################################
1838
1839
1840
1841
1842
1843
1844














1845
1846
1847
1848
1849
1850
1851
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900







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








  #############################################################################
  ####################### BEGIN Tcl & Eagle Constraints #######################
  #############################################################################

  tputs $test_channel [appendArgs \
      "---- start of common (Tcl & Eagle) test constraints...\n"]

  #
  # NOTE: Check for the test suite infrastructure files...
  #
  if {![info exists no(testSuiteFiles)]} then {
    checkForTestSuiteFiles $test_channel
  }

  #
  # NOTE: Has all use of [exec] for tests been disabled?
  #
  if {![info exists no(checkForTestExec)]} then {
    checkForTestExec $test_channel
  }

  #
  # NOTE: Has checking for the test machine been disabled?
  #
  if {![info exists no(testMachine)]} then {
    checkForTestMachine $test_channel
  }
2217
2218
2219
2220
2221
2222
2223
2224







2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2266
2267
2268
2269
2270
2271
2272

2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284



2285
2286
2287
2288
2289
2290
2291







-
+
+
+
+
+
+
+





-
-
-







  # NOTE: Has performance testing been disabled?
  #
  if {![info exists no(performance)]} then {
    checkForPerformance $test_channel
  }

  #
  # NOTE: Have precise timing tests been disabled?
  # NOTE: Have any timing related constraints been disabled?
  #
  # BUGBUG: In Eagle, these checks for "precision" timing are not overly
  #         reliable.  This may be due to the semi-random nature of the
  #         garbage collection.  More research into the precise cause of
  #         timing issues is certainly warranted.
  #
  #
  if {![info exists no(timing)]} then {
    checkForTiming $test_channel 50; # 1/20th second.
  }

  #
  # NOTE: Have very precise timing tests been disabled?
  #
  if {![info exists no(preciseTiming)]} then {
    checkForTiming $test_channel 25 preciseTiming; # 1/40th second.
  }

  #
  # NOTE: Has interactive testing been disabled?
  #
2327
2328
2329
2330
2331
2332
2333
2334

2335
2336
2337
2338
2339
2340
2341
2379
2380
2381
2382
2383
2384
2385

2386
2387
2388
2389
2390
2391
2392
2393







-
+







  #
  if {[isEagle]} then {
    #
    # NOTE: Get the source checkout and tags (i.e. of Eagle or whatever
    #       project the Eagle binaries are being used by) using a Fossil
    #       binary in the PATH, if available.
    #
    if {![info exists no(fossil)]} then {
    if {![info exists no(exec)] && ![info exists no(fossil)]} then {
      if {[catch {set exec [exec -- fossil info]}] == 0} then {
        set pattern {^checkout:\s+(.*?)\s+$}

        if {[regexp -line -- $pattern $exec dummy checkout] == 0} then {
          #
          # NOTE: We could not query the source checkout from Fossil.
          #
2439
2440
2441
2442
2443
2444
2445
2446

2447
2448
2449
2450
2451
2452
2453
2491
2492
2493
2494
2495
2496
2497

2498
2499
2500
2501
2502
2503
2504
2505







-
+







      [expr {[info exists test_file] && [string length $test_file] > 0 ? \
      $test_file : "<none>"}] \n]

  #
  # NOTE: Show the active test constraints.
  #
  tputs $test_channel [appendArgs "---- constraints: " \
      [formatList [lsort [getConstraints]]] \n]
      [formatList [lsort [getConstraints]] <none>] \n]

  #
  # NOTE: Show the starting command count (for both Tcl and Eagle).
  #
  tputs $test_channel [appendArgs "---- starting command count: " \
      [info cmdcount] \n]

Added Externals/NDoc3/bin/NDoc3.Documenter.Msdn.dll.

cannot compute difference between binary files

Added Externals/NDoc3/src/MsdnDocumenter.cs.



























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
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
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
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
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
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
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
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
// MsdnDocumenter.cs - a MSDN-like documenter
// Copyright (C) 2001  Kral Ferch, Jason Diamond
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Globalization;

using NDoc3.Core;
using NDoc3.Core.Reflection;
using NDoc3.Documenter.Msdn.onlinefiles;
using NDoc3.Documenter.Msdn.onlinetemplates;
using NDoc3.Xml;

namespace NDoc3.Documenter.Msdn
{
	/// <summary>The MsdnDocumenter class.</summary>
	public class MsdnDocumenter : BaseReflectionDocumenter
	{
		private enum WhichType
		{
			Class,
			Interface,
			Structure,
			Enumeration,
			Delegate,
			Unknown
		};

		private readonly Dictionary<WhichType, string> lowerCaseTypeNames;
		private readonly Dictionary<WhichType, string> mixedCaseTypeNames;
		private List<string> filesToInclude = new List<string>();

		/// <summary>
		/// Initializes a new instance of the <see cref="MsdnDocumenter" />
		/// class.
		/// </summary>
		public MsdnDocumenter(MsdnDocumenterConfig config)
			: base(config)
		{
			lowerCaseTypeNames = new Dictionary<WhichType, string>();
			lowerCaseTypeNames.Add(WhichType.Class, "class");
			lowerCaseTypeNames.Add(WhichType.Interface, "interface");
			lowerCaseTypeNames.Add(WhichType.Structure, "structure");
			lowerCaseTypeNames.Add(WhichType.Enumeration, "enumeration");
			lowerCaseTypeNames.Add(WhichType.Delegate, "delegate");

			mixedCaseTypeNames = new Dictionary<WhichType, string>();
			mixedCaseTypeNames.Add(WhichType.Class, "Class");
			mixedCaseTypeNames.Add(WhichType.Interface, "Interface");
			mixedCaseTypeNames.Add(WhichType.Structure, "Structure");
			mixedCaseTypeNames.Add(WhichType.Enumeration, "Enumeration");
			mixedCaseTypeNames.Add(WhichType.Delegate, "Delegate");
		}

		/// <summary>See <see cref="IDocumenter"/>.</summary>
		public override string MainOutputFile
		{
			get
			{
				if ((MyConfig.OutputTarget & OutputType.HtmlHelp) > 0) {
					return Path.Combine(MyConfig.OutputDirectory,
						MyConfig.HtmlHelpName + ".chm");
				}
				return Path.Combine(MyConfig.OutputDirectory, "index.html");
			}
		}

		/// <summary>See <see cref="IDocumenter"/>.</summary>
		public override string CanBuild(Project project, bool checkInputOnly)
		{
			string result = base.CanBuild(project, checkInputOnly);
			if (result != null) {
				return result;
			}

			string AdditionalContentResourceDirectory = MyConfig.AdditionalContentResourceDirectory;
			if (AdditionalContentResourceDirectory.Length != 0 && !Directory.Exists(AdditionalContentResourceDirectory))
				return string.Format("The Additional Content Resource Directory {0} could not be found", AdditionalContentResourceDirectory);

			string ExtensibilityStylesheet = MyConfig.ExtensibilityStylesheet;
			if (ExtensibilityStylesheet.Length != 0 && !File.Exists(ExtensibilityStylesheet))
				return string.Format("The Extensibility Stylesheet file {0} could not be found", ExtensibilityStylesheet);

			if (checkInputOnly) {
				return null;
			}

			string path = Path.Combine(MyConfig.OutputDirectory,
				MyConfig.HtmlHelpName + ".chm");

			string temp = Path.Combine(MyConfig.OutputDirectory, "~chm.tmp");

			try {

				if (File.Exists(path)) {
					//if we can move the file, then it is not open...
					File.Move(path, temp);
					File.Move(temp, path);
				}
			} catch (Exception) {
				result = "The compiled HTML Help file is probably open.\nPlease close it and try again.";
			}

			return result;
		}

		/// <summary>See <see cref="IDocumenter"/>.</summary>
		public override void Build(Project project)
		{
			BuildProjectContext buildContext = new BuildProjectContext(new CultureInfo(MyConfig.LangID),
				new DirectoryInfo(MyConfig.OutputDirectory), MyConfig.CleanIntermediates);

			try {
				OnDocBuildingStep(0, "Initializing...");

				buildContext.Initialize();

				OnDocBuildingStep(10, "Merging XML documentation...");

				// Will hold the name of the file name containing the XML doc
				XmlDocument projectXml = CreateNDocXml(project);
				buildContext.SetProjectXml(projectXml, MyConfig.MergeAssemblies);

				OnDocBuildingStep(30, "Loading XSLT files...");

				buildContext.stylesheets = StyleSheetCollection.LoadStyleSheets(MyConfig.ExtensibilityStylesheet);

				OnDocBuildingStep(40, "Generating HTML pages...");

				// setup for root page
				string defaultTopic;
				string rootPageFileName = null;
				string rootPageTOCName = null;

				if (!String.IsNullOrEmpty(MyConfig.RootPageFileName)) {
					rootPageFileName = MyConfig.RootPageFileName;
					defaultTopic = "default.html";

					rootPageTOCName = "Overview";
					// what to call the top page in the table of contents?
					if (!String.IsNullOrEmpty(MyConfig.RootPageTOCName)) {
						rootPageTOCName = MyConfig.RootPageTOCName;
					}
				} else {
					// TODO (EE): check MergeAssemblies and adjust defaultTopic accordingly
					XmlNode defaultNamespace;
					if (MyConfig.MergeAssemblies)
					{
						XmlNodeList namespaceNodes = buildContext.SelectNodes("/ndoc:ndoc/ndoc:assembly/ndoc:module/ndoc:namespace");
						int[] indexes = SortNodesByAttribute(namespaceNodes, "name");

						defaultNamespace = namespaceNodes[indexes[0]];
					}
					else
					{
						XmlNodeList assemblyNodes = buildContext.SelectNodes("/ndoc:ndoc/ndoc:assembly");
						int[] assemblyIndexes = SortNodesByAttribute(assemblyNodes, "name");
						XmlNode defaultAssemblyNode = assemblyNodes[assemblyIndexes[0]];
						XmlNodeList namespaceNodes = buildContext.SelectNodes(defaultAssemblyNode, "ndoc:module/ndoc:namespace");
						int[] indexes = SortNodesByAttribute(namespaceNodes, "name");
						defaultNamespace = namespaceNodes[indexes[0]];
					}
					string defaultNamespaceName = GetNodeName(defaultNamespace);
					string assemblyName = GetNodeName(buildContext.SelectSingleNode(defaultNamespace, "ancestor::ndoc:assembly"));
					defaultTopic = buildContext._nameResolver.GetFilenameForNamespace(assemblyName, defaultNamespaceName);
				}
				buildContext.htmlHelp = SetupHtmlHelpBuilder(buildContext.WorkingDirectory, defaultTopic);

				using (buildContext.htmlHelp.OpenProjectFile())
				using (buildContext.htmlHelp.OpenContentsFile(string.Empty, true)) {
					// Write the embedded css files to the html output directory
					WriteHtmlContentResources(buildContext);

					GenerateHtmlContentFiles(buildContext, rootPageFileName, rootPageTOCName);
				}

				HtmlHelp htmlHelp = buildContext.htmlHelp;
				htmlHelp.WriteEmptyIndexFile();

				if ((MyConfig.OutputTarget & OutputType.Web) > 0) {
					OnDocBuildingStep(75, "Generating HTML index file...");

					// Write the embedded online templates to the html output directory
					GenerateHtmlIndexFile(buildContext, defaultTopic);
				}

				if ((MyConfig.OutputTarget & OutputType.HtmlHelp) > 0) {
					OnDocBuildingStep(85, "Compiling HTML Help file...");
					htmlHelp.CompileProject();
				}
#if !DEBUG
				else
				{
					//remove .hhc file
					File.Delete(htmlHelp.GetPathToContentsFile());
				}
#endif

				// if we're only building a CHM, copy that to the Outpur dir
				if ((MyConfig.OutputTarget & OutputType.HtmlHelp) > 0 && (MyConfig.OutputTarget & OutputType.Web) == 0) {
					buildContext.SaveOutputs("*.chm");
				} else {
					// otherwise copy everything to the output dir (cause the help file is all the html, not just one chm)
					buildContext.SaveOutputs("*.*");
				}

				OnDocBuildingStep(100, "Done.");
			} catch(DocumenterException) {
				throw;
			} catch (Exception ex) {
				throw new DocumenterException(ex.Message, ex);
			} finally {
				buildContext.Dispose();
			}
		}

		private void GenerateHtmlIndexFile(BuildProjectContext ctx, string defaultTopic)
		{
			EmbeddedResources.WriteEmbeddedResources(typeof(OnlineFilesLocationHint), ctx.WorkingDirectory);

			using (TemplateWriter indexWriter = new TemplateWriter(
				Path.Combine(ctx.WorkingDirectory.FullName, "index.html"),
				EmbeddedResources.GetEmbeddedResourceReader(typeof(OnlineTemplatesLocationHint), "index.html", null))) {
				indexWriter.CopyToLine("\t\t<title><%TITLE%></title>");
				indexWriter.WriteLine("\t\t<title>" + MyConfig.HtmlHelpName + "</title>");
				indexWriter.CopyToLine("\t\t<frame name=\"main\" src=\"<%HOME_PAGE%>\" frameborder=\"1\">");
				indexWriter.WriteLine("\t\t<frame name=\"main\" src=\"" + defaultTopic + "\" frameborder=\"1\">");
				indexWriter.CopyToEnd();
				indexWriter.Close();
			}

			Trace.WriteLine("transform the HHC contents file into html");
#if DEBUG
			int start = Environment.TickCount;
#endif
			//transform the HHC contents file into html
			using (StreamReader contentsFile = new StreamReader(ctx.HtmlHelpContentFilePath.FullName, ctx.CurrentFileEncoding)) {
				XPathDocument xpathDocument = new XPathDocument(contentsFile);
				string contentsFilename = Path.Combine(ctx.WorkingDirectory.FullName, "contents.html");
				using (StreamWriter streamWriter = new StreamWriter(
					File.Open(contentsFilename, FileMode.CreateNew, FileAccess.Write, FileShare.None), ctx.CurrentFileEncoding)) {
					XslTransform(ctx, "htmlcontents", xpathDocument, null, streamWriter, contentsFilename);
				}
			}
#if DEBUG
			Trace.WriteLine(string.Format("{0} msec.", (Environment.TickCount - start)));
#endif
		}

		private HtmlHelp SetupHtmlHelpBuilder(DirectoryInfo workingDirectory, string defaultTopic)
		{
			HtmlHelp htmlHelp = new HtmlHelp(
				workingDirectory,
				MyConfig.HtmlHelpName,
				defaultTopic,
				((MyConfig.OutputTarget & OutputType.HtmlHelp) == 0));
			htmlHelp.IncludeFavorites = MyConfig.IncludeFavorites;
			htmlHelp.BinaryTOC = MyConfig.BinaryTOC;
			htmlHelp.LangID = MyConfig.LangID;
			return htmlHelp;
		}

		private void GenerateHtmlContentFiles(BuildProjectContext buildContext, string rootPageFileName, string rootPageTOCName)
		{
			if (!String.IsNullOrEmpty(MyConfig.CopyrightHref)) {
				if (!MyConfig.CopyrightHref.StartsWith("http:")) {
					string copyrightFile = Path.Combine(buildContext.WorkingDirectory.FullName, Path.GetFileName(MyConfig.CopyrightHref));
					File.Copy(MyConfig.CopyrightHref, copyrightFile, true);
					File.SetAttributes(copyrightFile, FileAttributes.Archive);
					buildContext.htmlHelp.AddFileToProject(Path.GetFileName(MyConfig.CopyrightHref));
				}
			}

			// add root page if requested
			if (rootPageFileName != null) {
				if (!File.Exists(rootPageFileName)) {
					throw new DocumenterException("Cannot find the documentation's root page file:\n"
												  + rootPageFileName);
				}

				// add the file
				string rootPageOutputName = Path.Combine(buildContext.WorkingDirectory.FullName, "default.html");
				if (Path.GetFullPath(rootPageFileName) != Path.GetFullPath(rootPageOutputName)) {
					File.Copy(rootPageFileName, rootPageOutputName, true);
					File.SetAttributes(rootPageOutputName, FileAttributes.Archive);
				}
				buildContext.htmlHelp.AddFileToProject(Path.GetFileName(rootPageOutputName));
				buildContext.htmlHelp.AddFileToContents(rootPageTOCName,
										   Path.GetFileName(rootPageOutputName));

				// depending on peer setting, make root page the container
				if (MyConfig.RootPageContainsNamespaces)
					buildContext.htmlHelp.OpenBookInContents();
			}

			MakeHtmlForAssemblies(buildContext, MyConfig.MergeAssemblies);
			foreach (string filename in filesToInclude) {
				buildContext.htmlHelp.AddFileToProject(filename);
			}

			// close root book if applicable
			if (rootPageFileName != null) {
				if (MyConfig.RootPageContainsNamespaces)
					buildContext.htmlHelp.CloseBookInContents();
			}
		}

		private XmlDocument CreateNDocXml(Project project)
		{
			string tempFileName = null;
			try {
				// determine temp file name
				tempFileName = Path.GetTempFileName();
				// Let the Documenter base class do it's thing.
				MakeXmlFile(project, new FileInfo(tempFileName));

				// Load the XML documentation into DOM and XPATH doc.
				using (FileStream tempFile = File.Open(tempFileName, FileMode.Open, FileAccess.Read)) {

					XmlDocument xml = new XmlDocument();
					xml.Load(tempFile);
					return xml;
				}
			} finally {
				if (tempFileName != null && File.Exists(tempFileName)) {
#if DEBUG
					File.Copy(tempFileName, MyConfig.OutputDirectory.TrimEnd('\\', '/') + "\\ndoc.xml", true);
#endif
					File.Delete(tempFileName);
				}
			}
		}

		private void WriteHtmlContentResources(BuildProjectContext buildContext)
		{
			EmbeddedResources.WriteEmbeddedResources(
				GetType().Module.Assembly,
				GetType().Namespace + ".css",
				buildContext.WorkingDirectory);

			// Write the embedded icons to the html output directory
			EmbeddedResources.WriteEmbeddedResources(
				GetType().Module.Assembly,
				GetType().Namespace + ".images",
				buildContext.WorkingDirectory);

			// Write the embedded scripts to the html output directory
			EmbeddedResources.WriteEmbeddedResources(
				GetType().Module.Assembly,
				GetType().Namespace + ".scripts",
				buildContext.WorkingDirectory);

			if (((string)MyConfig.AdditionalContentResourceDirectory).Length > 0)
				buildContext.CopyToWorkingDirectory(new DirectoryInfo(MyConfig.AdditionalContentResourceDirectory));

			// Write the external files (FilesToInclude) to the html output directory

			foreach (string srcFilePattern in MyConfig.FilesToInclude.Split('|')) {
				if (string.IsNullOrEmpty(srcFilePattern))
					continue;

				string path = Path.GetDirectoryName(srcFilePattern);
				string pattern = Path.GetFileName(srcFilePattern);

				// Path.GetDirectoryName can return null in some cases.
				// Treat this as an empty string.
				if (path == null)
					path = string.Empty;

				// Make sure we have a fully-qualified path name
				if (!Path.IsPathRooted(path))
					path = Path.Combine(Environment.CurrentDirectory, path);

				// Directory.GetFiles does not accept null or empty string
				// for the searchPattern parameter. When no pattern was
				// specified, assume all files (*) are wanted.
				if (string.IsNullOrEmpty(pattern))
					pattern = "*";

				foreach (string srcFile in Directory.GetFiles(path, pattern)) {
					string dstFile = Path.Combine(buildContext.WorkingDirectory.FullName, Path.GetFileName(srcFile));
					File.Copy(srcFile, dstFile, true);
					File.SetAttributes(dstFile, FileAttributes.Archive);
					filesToInclude.Add(dstFile);
				}
			}
		}

		private static void XslTransform(BuildProjectContext buildContext, string stylesheetName, IXPathNavigable xpathNavigable, XsltArgumentList arguments, TextWriter writer, string targetFilename)
		{
			StyleSheet stylesheet = buildContext.stylesheets[stylesheetName];
			try {
				stylesheet.Transform(xpathNavigable, arguments, writer);
			} catch (XsltException ex) {
				throw new DocumenterException(string.Format("XSLT error while writing file {0} using stylesheet {1}({2}:{3}) : {4}", targetFilename, stylesheetName, ex.LineNumber, ex.LinePosition, ex.Message));
			}
		}

		private MsdnDocumenterConfig MyConfig
		{
			get
			{
				return (MsdnDocumenterConfig)Config;
			}
		}

		private static WhichType GetWhichType(XmlNode typeNode)
		{
			WhichType whichType;

			switch (typeNode.Name) {
				case "class":
					whichType = WhichType.Class;
					break;
				case "interface":
					whichType = WhichType.Interface;
					break;
				case "structure":
					whichType = WhichType.Structure;
					break;
				case "enumeration":
					whichType = WhichType.Enumeration;
					break;
				case "delegate":
					whichType = WhichType.Delegate;
					break;
				default:
					whichType = WhichType.Unknown;
					break;
			}

			return whichType;
		}

		private void MakeHtmlForAssemblies(BuildProjectContext ctx, bool mergeAssemblies)
		{
#if DEBUG
			int start = Environment.TickCount;
#endif

			MakeHtmlForAssembliesSorted(ctx, mergeAssemblies);

#if DEBUG
			Trace.WriteLine("Making Html: " + ((Environment.TickCount - start) / 1000.0) + " sec.");
#endif
		}

		private void MakeHtmlForAssembliesSorted(BuildProjectContext ctx, bool mergeAssemblies)
		{
			const string defaultNamespace = null;

			XmlNodeList assemblyNodes = ctx.SelectNodes("/ndoc:ndoc/ndoc:assembly");

			List<string> assemblyNames = new List<string>();
			foreach(XmlNode node in assemblyNodes) assemblyNames.Add(GetNodeName(node));
			assemblyNames.Sort();

			if (mergeAssemblies)
            {
                // sort namespaces alphabetically except for defaultNamespace, which is always first
				string[] namespaces = SortNamespaces(ctx, assemblyNames, defaultNamespace);
				MakeHtmlForNamespaces(ctx, null, namespaces);                
            }
            else
            {
                foreach (string currentAssemblyName in assemblyNames)
                {
                    MakeHtmlForAssembly(ctx, currentAssemblyName);

					ctx.htmlHelp.OpenBookInContents();
                    string[] namespaces = SortNamespaces(ctx, new List<string>( new[] { currentAssemblyName }) , defaultNamespace);
					MakeHtmlForNamespaces(ctx, currentAssemblyName, namespaces);
					ctx.htmlHelp.CloseBookInContents();
                }
            }
        }

		private void MakeHtmlForAssembly(BuildProjectContext ctx, string assemblyName)
		{
			BuildAssemblyContext actx = new BuildAssemblyContext(ctx, assemblyName);
			string fileName = ctx._nameResolver.GetFilenameForAssembly(assemblyName);

			XsltArgumentList arguments = new XsltArgumentList();
			arguments.AddParam("assembly-name", String.Empty, assemblyName);
			TransformAndWriteResult(actx, "assembly", arguments, fileName);

			ctx.htmlHelp.AddFileToContents(assemblyName + " Assembly", fileName, HtmlHelpIcon.Page);
		}

		private void MakeHtmlForNamespaces(BuildProjectContext ctx, string currentAssembly, IList<string> namespaces)
		{
			int nNodes = namespaces.Count;

			bool heirTOC = (MyConfig.NamespaceTOCStyle == TOCStyle.Hierarchical);
			int level = 0;

			string[] last = new string[0];

			BuildAssemblyContext generatorContext = null;
			for (int i = 0; i < nNodes; i++) {
				OnDocBuildingProgress(i * 100 / nNodes); // TODO (EE): fix calc for !MergeAssemblies mode

				string currentNamespace = namespaces[i];
				// determine assembly containing this namespace
				XmlNodeList namespaceNodes = (currentAssembly==null) 
					? ctx.SelectNodes(string.Format("/ndoc:ndoc/ndoc:assembly/ndoc:module/ndoc:namespace[@name='{0}']", currentNamespace))
					: ctx.SelectNodes(string.Format("/ndoc:ndoc/ndoc:assembly[@name='{0}']/ndoc:module/ndoc:namespace[@name='{1}']", currentAssembly, currentNamespace));

				string assemblyName = GetNodeName(ctx.SelectSingleNode(namespaceNodes[0], "ancestor::ndoc:assembly"));
				generatorContext = new BuildAssemblyContext(ctx, assemblyName);

				if (heirTOC) {
					string[] split = currentNamespace.Split('.');

					for (level = last.Length; level >= 0 &&
						ArrayEquals(split, 0, last, 0, level) == false; level--) {
						if (level > last.Length)
							continue;

						string namespaceName = string.Join(".", last, 0, level);
						XmlNodeList typeNodes = GetTypeNodes(ctx, currentAssembly, namespaceName);
						MakeHtmlForTypes(generatorContext, typeNodes);
						ctx.htmlHelp.CloseBookInContents();
					}

					if (level < 0)
						level = 0;

					for (; level < split.Length; level++) {
						string namespaceName = string.Join(".", split, 0, level + 1);

						if (!namespaces.Contains(namespaceName))
//						if (Array.BinarySearch(namespaces, namespaceName) < 0)
							MakeHtmlForNamespace(generatorContext, split[level], namespaceName, false);
						else
							MakeHtmlForNamespace(generatorContext, split[level], namespaceName, true);

						ctx.htmlHelp.OpenBookInContents();
					}

					last = split;
				} else {
					MakeHtmlForNamespace(generatorContext, currentNamespace, currentNamespace, true);
					using (ctx.htmlHelp.OpenBookInContents()) {
						XmlNodeList typeNodes = GetTypeNodes(ctx, currentAssembly, currentNamespace);
						MakeHtmlForTypes(generatorContext, typeNodes);
					}
				}
			}


			if (heirTOC && last.Length > 0) {
				for (; level >= 1; level--) {
					string ns = string.Join(".", last, 0, level);
					XmlNodeList typeNodes = GetTypeNodes(ctx, currentAssembly, ns);
					MakeHtmlForTypes(generatorContext, typeNodes);
					ctx.htmlHelp.CloseBookInContents();
				}
			}

			OnDocBuildingProgress(100);
		}

		private static XmlNodeList GetTypeNodes(BuildProjectContext ctx, string assembly, string namespaceName)
		{
			string xpath = (assembly == null)
			               	? string.Format(
			               	  	"/ndoc:ndoc/ndoc:assembly/ndoc:module/ndoc:namespace[@name='{0}']/*[local-name()!='documentation' and local-name()!='typeHierarchy']",
			               	  	namespaceName)
			               	: string.Format(
			               	  	"/ndoc:ndoc/ndoc:assembly[@name='{0}']/ndoc:module/ndoc:namespace[@name='{1}']/*[local-name()!='documentation' and local-name()!='typeHierarchy']",
								assembly,
			               	  	namespaceName);
			XmlNodeList typeNodes = ctx.SelectNodes(xpath);
			return typeNodes;			
		}

		private static bool ArrayEquals(string[] array1, int from1, string[] array2, int from2, int count)
		{
			for (int i = 0; i < count; i++) {
				if (array1[from1 + i] != array2[from2 + i])
					return false;
			}

			return true;
		}

		private static void GetNamespacesFromAssembly(BuildProjectContext buildContext, string assemblyName, NameValueCollection namespaceAssemblies)
		{
			XmlNodeList namespaceNodes = buildContext.SelectNodes(string.Format("/ndoc:ndoc/ndoc:assembly[@name='{0}']/ndoc:module/ndoc:namespace", assemblyName));
			foreach (XmlNode namespaceNode in namespaceNodes) {
				string namespaceName = GetNodeName(namespaceNode);
				namespaceAssemblies.Add(namespaceName, assemblyName);
			}
		}

		/// <summary>
		/// Add the namespace elements to the output
		/// </summary>
		/// <remarks>
		/// The namespace 
		/// </remarks>
		/// <param name="ctx"></param>
		/// <param name="namespacePart">If nested, the namespace part will be the current
		/// namespace element being documented</param>
		/// <param name="namespaceName">The full namespace name being documented</param>
		/// <param name="addDocumentation">If true, the namespace will be documented, if false
		/// the node in the TOC will not link to a page</param>
		private void MakeHtmlForNamespace(BuildAssemblyContext ctx, string namespacePart, string namespaceName,
			bool addDocumentation)
		{
			//			// handle duplicate namespace documentation
			//			if (ctx.documentedNamespaces.Contains(namespaceName)) 
			//				return;
			//			ctx.documentedNamespaces.Add(namespaceName);

			if (addDocumentation) {
				string currentAssemblyName = (ctx.MergeAssemblies) ? string.Empty : ctx.CurrentAssemblyName;

				string namespaceFilename = ctx._nameResolver.GetFilenameForNamespace(currentAssemblyName, namespaceName);

				ctx.htmlHelp.AddFileToContents(namespacePart, namespaceFilename);

				XsltArgumentList arguments = new XsltArgumentList();
				arguments.AddParam("merge-assemblies", String.Empty, ctx.MergeAssemblies);
				arguments.AddParam("namespace", String.Empty, namespaceName);
				TransformAndWriteResult(ctx, "namespace", arguments, namespaceFilename);

				string namespaceHierarchyFilename = ctx._nameResolver.GetFilenameForNamespaceHierarchy(currentAssemblyName, namespaceName);
				arguments = new XsltArgumentList();
				arguments.AddParam("merge-assemblies", String.Empty, ctx.MergeAssemblies);
				arguments.AddParam("namespace", String.Empty, namespaceName);
				TransformAndWriteResult(ctx, "namespacehierarchy", arguments, namespaceHierarchyFilename);
			} else {
				ctx.htmlHelp.AddFileToContents(namespacePart);
			}
		}

		private void MakeHtmlForTypes(BuildProjectContext projectCtx, XmlNodeList typeNodes)
		{
			int[] indexes = SortNodesByAttribute(typeNodes, "id");
			int nNodes = typeNodes.Count;

			for (int i = 0; i < nNodes; i++) {
				XmlNode typeNode = typeNodes[indexes[i]];
				WhichType whichType = GetWhichType(typeNode);

				string assemblyName = XmlUtils.GetNodeName(projectCtx.SelectSingleNode(typeNode, "ancestor::ndoc:assembly"));
				BuildAssemblyContext ctx = new BuildAssemblyContext(projectCtx, assemblyName); // TODO (EE): initialize w/ assembly name

				switch (whichType) {
					case WhichType.Class:
						MakeHtmlForInterfaceOrClassOrStructure(ctx, whichType, typeNode);
						break;
					case WhichType.Interface:
						MakeHtmlForInterfaceOrClassOrStructure(ctx, whichType, typeNode);
						break;
					case WhichType.Structure:
						MakeHtmlForInterfaceOrClassOrStructure(ctx, whichType, typeNode);
						break;
					case WhichType.Enumeration:
						MakeHtmlForEnumerationOrDelegate(ctx, whichType, typeNode);
						break;
					case WhichType.Delegate:
						MakeHtmlForEnumerationOrDelegate(ctx, whichType, typeNode);
						break;
					default:
						break;
				}
			}
		}

		private void MakeHtmlForEnumerationOrDelegate(BuildAssemblyContext ctx, WhichType whichType, XmlNode typeNode)
		{
			string typeName = whichType == WhichType.Delegate ? GetNodeDisplayName(typeNode) : GetNodeName(typeNode);
			string typeID = GetNodeId(typeNode);
			string fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, typeID);

			ctx.htmlHelp.AddFileToContents(typeName + " " + mixedCaseTypeNames[whichType], fileName, HtmlHelpIcon.Page);

			XsltArgumentList arguments = new XsltArgumentList();
			arguments.AddParam("type-id", String.Empty, typeID);
			TransformAndWriteResult(ctx, "type", arguments, fileName);
		}

		private void MakeHtmlForInterfaceOrClassOrStructure(BuildAssemblyContext ctx,
			WhichType whichType,
			XmlNode typeNode)
		{
			string typeName = GetNodeDisplayName(typeNode);
			string typeID = GetNodeId(typeNode);
			string fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, typeID);

			ctx.htmlHelp.AddFileToContents(typeName + " " + mixedCaseTypeNames[whichType], fileName);

			bool hasMembers = ctx.SelectNodes(typeNode, "ndoc:constructor|ndoc:field|ndoc:property|ndoc:method|ndoc:operator|ndoc:event").Count > 0;

			if (hasMembers) {
				ctx.htmlHelp.OpenBookInContents();
			}

			XsltArgumentList arguments = new XsltArgumentList();
			arguments.AddParam("type-id", String.Empty, typeID);
			TransformAndWriteResult(ctx, "type", arguments, fileName);

			if (ctx.SelectNodes(typeNode, "ndoc:derivedBy").Count > 5) {
				fileName = ctx._nameResolver.GetFilenameForTypeHierarchy(ctx.CurrentAssemblyName, typeID);
				arguments = new XsltArgumentList();
				arguments.AddParam("type-id", String.Empty, typeID);
				TransformAndWriteResult(ctx, "typehierarchy", arguments, fileName);
			}

			if (hasMembers) {
				fileName = ctx._nameResolver.GetFilenameForTypeMemberList(ctx.CurrentAssemblyName, typeID);
				ctx.htmlHelp.AddFileToContents(typeName + " Members",
					fileName,
					HtmlHelpIcon.Page);

				arguments = new XsltArgumentList();
				arguments.AddParam("type-id", String.Empty, typeID);
				TransformAndWriteResult(ctx, "allmembers", arguments, fileName);

				MakeHtmlForConstructors(ctx, typeNode);
				MakeHtmlForFields(ctx, typeNode);
				MakeHtmlForProperties(ctx, typeNode);
				MakeHtmlForMethods(ctx, typeNode);
				MakeHtmlForOperators(ctx, typeNode);
				MakeHtmlForEvents(ctx, typeNode);

				ctx.htmlHelp.CloseBookInContents();
			}
		}

		private void MakeHtmlForConstructors(BuildAssemblyContext ctx, XmlNode typeNode)
		{
			string constructorID;
			string fileName;

			string typeName = GetNodeDisplayName(typeNode);
			string typeID = GetNodeId(typeNode);

			XmlNodeList constructorNodes = ctx.SelectNodes(typeNode, "ndoc:constructor[@contract!='Static']");
			// If the constructor is overloaded then make an overload page.
			if (constructorNodes.Count > 1) {
				fileName = ctx._nameResolver.GetFilenameForConstructorList(ctx.CurrentAssemblyName, typeID);
				ctx.htmlHelp.AddFileToContents(typeName + " Constructor", fileName);

				ctx.htmlHelp.OpenBookInContents();

				constructorID = constructorNodes[0].Attributes["id"].Value;

				XsltArgumentList arguments = new XsltArgumentList();
				arguments.AddParam("member-id", String.Empty, constructorID);
				TransformAndWriteResult(ctx, "memberoverload", arguments, fileName);
			}

			foreach (XmlNode constructorNode in constructorNodes) {
				constructorID = constructorNode.Attributes["id"].Value;
				fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, constructorID);

				if (constructorNodes.Count > 1) {
					XmlNodeList parameterNodes = ctx.SelectNodes(constructorNode, "ndoc:parameter");
					ctx.htmlHelp.AddFileToContents(typeName + " Constructor " + GetParamList(parameterNodes), fileName,
						HtmlHelpIcon.Page);
				} else {
					ctx.htmlHelp.AddFileToContents(typeName + " Constructor", fileName, HtmlHelpIcon.Page);
				}

				XsltArgumentList arguments = new XsltArgumentList();
				arguments.AddParam("member-id", String.Empty, constructorID);
				TransformAndWriteResult(ctx, "member", arguments, fileName);
			}

			if (constructorNodes.Count > 1) {
				ctx.htmlHelp.CloseBookInContents();
			}

			XmlNode staticConstructorNode = ctx.SelectSingleNode(typeNode, "ndoc:constructor[@contract='Static']");
			if (staticConstructorNode != null) {
				constructorID = staticConstructorNode.Attributes["id"].Value;
				fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, constructorID);

				ctx.htmlHelp.AddFileToContents(typeName + " Static Constructor", fileName, HtmlHelpIcon.Page);

				XsltArgumentList arguments = new XsltArgumentList();
				arguments.AddParam("member-id", String.Empty, constructorID);
				TransformAndWriteResult(ctx, "member", arguments, fileName);
			}
		}

		private void MakeHtmlForFields(BuildAssemblyContext ctx, XmlNode typeNode)
		{
			XmlNodeList fields = ctx.SelectNodes(typeNode, "ndoc:field[not(@declaringType)]");

			if (fields.Count > 0) {
				//string typeName = typeNode.Attributes["name"].Value;
				string typeID = GetNodeId(typeNode);
				string fileName = ctx._nameResolver.GetFilenameForFieldList(ctx.CurrentAssemblyName, typeID);

				ctx.htmlHelp.AddFileToContents("Fields", fileName);

				XsltArgumentList arguments = new XsltArgumentList();
				arguments.AddParam("type-id", String.Empty, typeID);
				arguments.AddParam("member-type", String.Empty, "field");
				TransformAndWriteResult(ctx, "individualmembers", arguments, fileName);

				ctx.htmlHelp.OpenBookInContents();

				int[] indexes = SortNodesByAttribute(fields, "id");

				foreach (int index in indexes) {
					XmlNode field = fields[index];

					string fieldName = GetNodeName(field);
					string fieldID = GetNodeId(field);
					fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, fieldID);
					ctx.htmlHelp.AddFileToContents(fieldName + " Field", fileName, HtmlHelpIcon.Page);

					arguments = new XsltArgumentList();
					arguments.AddParam("field-id", String.Empty, fieldID);
					TransformAndWriteResult(ctx, "field", arguments, fileName);
				}

				ctx.htmlHelp.CloseBookInContents();
			}
		}

		private void MakeHtmlForProperties(BuildAssemblyContext ctx, XmlNode typeNode)
		{
			XmlNodeList declaredPropertyNodes = ctx.SelectNodes(typeNode, "ndoc:property[not(@declaringType)]");

			if (declaredPropertyNodes.Count > 0) {
				XmlNode propertyNode;
				bool bOverloaded = false;
				int i;

				string typeID = GetNodeId(typeNode);
				XmlNodeList propertyNodes = ctx.SelectNodes(typeNode, "ndoc:property[not(@declaringType)]");
				int nNodes = propertyNodes.Count;

				int[] indexes = SortNodesByAttribute(propertyNodes, "id");

				string fileName = ctx._nameResolver.GetFilenameForPropertyList(ctx.CurrentAssemblyName, typeID);
				ctx.htmlHelp.AddFileToContents("Properties", fileName);

				XsltArgumentList arguments = new XsltArgumentList();
				arguments.AddParam("type-id", String.Empty, typeID);
				arguments.AddParam("member-type", String.Empty, "property");
				TransformAndWriteResult(ctx, "individualmembers", arguments, fileName);

				ctx.htmlHelp.OpenBookInContents();

				for (i = 0; i < nNodes; i++) {
					propertyNode = propertyNodes[indexes[i]];

					string propertyName = propertyNode.Attributes["name"].Value;
					string propertyID = propertyNode.Attributes["id"].Value;

					// If the method is overloaded then make an overload page.
					string previousPropertyName = ((i - 1 < 0) || (propertyNodes[indexes[i - 1]].Attributes.Count == 0))
													? "" : propertyNodes[indexes[i - 1]].Attributes[0].Value;
					string nextPropertyName = ((i + 1 == nNodes) || (propertyNodes[indexes[i + 1]].Attributes.Count == 0))
												? "" : propertyNodes[indexes[i + 1]].Attributes[0].Value;

					if ((previousPropertyName != propertyName) && (nextPropertyName == propertyName)) {
						fileName = ctx._nameResolver.GetFilenameForPropertyOverloads(ctx.CurrentAssemblyName, typeID, propertyName);
						ctx.htmlHelp.AddFileToContents(propertyName + " Property", fileName);

						arguments = new XsltArgumentList();
						arguments.AddParam("member-id", String.Empty, propertyID);
						TransformAndWriteResult(ctx, "memberoverload", arguments, fileName);

						ctx.htmlHelp.OpenBookInContents();

						bOverloaded = true;
					}

					fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, propertyID);

					string pageTitle;
					if (!bOverloaded) {
						pageTitle = string.Format("{0} Property", propertyName);
					} else {
						XmlNodeList parameterNodes = ctx.SelectNodes(propertyNode, "ns:parameter");
						pageTitle = string.Format("{0} Property {1}", propertyName, GetParamList(parameterNodes));
					}
					ctx.htmlHelp.AddFileToContents(pageTitle, fileName, HtmlHelpIcon.Page);

					XsltArgumentList arguments2 = new XsltArgumentList();
					arguments2.AddParam("property-id", String.Empty, propertyID);
					TransformAndWriteResult(ctx, "property", arguments2, fileName);

					if ((previousPropertyName == propertyName) && (nextPropertyName != propertyName)) {
						ctx.htmlHelp.CloseBookInContents();
						bOverloaded = false;
					}
				}

				ctx.htmlHelp.CloseBookInContents();
			}
		}

		private static string GetPreviousMethodName(XmlNodeList methodNodes, int[] indexes, int index)
		{
			while (--index >= 0) {
				if (methodNodes[indexes[index]].Attributes["declaringType"] == null)
					return methodNodes[indexes[index]].Attributes["name"].Value;
			}
			return null;
		}

		private static string GetNextMethodName(XmlNodeList methodNodes, int[] indexes, int index)
		{
			while (++index < methodNodes.Count) {
				if (methodNodes[indexes[index]].Attributes["declaringType"] == null)
					return methodNodes[indexes[index]].Attributes["name"].Value;
			}
			return null;
		}

		// returns true, if method is neither overload of a method in the same class,
		// nor overload of a method in the base class.
		private static bool IsMethodAlone(XmlNodeList methodNodes, int[] indexes, int index)
		{
			string name = methodNodes[indexes[index]].Attributes["name"].Value;
			int lastIndex = methodNodes.Count - 1;
			if (lastIndex <= 0)
				return true;
			bool previousNameDifferent = (index == 0)
				|| (methodNodes[indexes[index - 1]].Attributes["name"].Value != name);
			bool nextNameDifferent = (index == lastIndex)
				|| (methodNodes[indexes[index + 1]].Attributes["name"].Value != name);
			return (previousNameDifferent && nextNameDifferent);
		}

		private static bool IsMethodFirstOverload(XmlNodeList methodNodes, int[] indexes, int index)
		{
			if ((methodNodes[indexes[index]].Attributes["declaringType"] != null)
				|| IsMethodAlone(methodNodes, indexes, index))
				return false;

			string name = methodNodes[indexes[index]].Attributes["name"].Value;
			string previousName = GetPreviousMethodName(methodNodes, indexes, index);
			return previousName != name;
		}

		private static bool IsMethodLastOverload(XmlNodeList methodNodes, int[] indexes, int index)
		{
			if ((methodNodes[indexes[index]].Attributes["declaringType"] != null)
				|| IsMethodAlone(methodNodes, indexes, index))
				return false;

			string name = methodNodes[indexes[index]].Attributes["name"].Value;
			string nextName = GetNextMethodName(methodNodes, indexes, index);
			return nextName != name;
		}

		private void MakeHtmlForMethods(BuildAssemblyContext ctx, XmlNode typeNode)
		{
			XmlNodeList declaredMethodNodes = ctx.SelectNodes(typeNode, "ndoc:method[not(@declaringType)]");

			if (declaredMethodNodes.Count > 0) {
				bool bOverloaded = false;

				string typeID = GetNodeId(typeNode);
				XmlNodeList methodNodes = ctx.SelectNodes(typeNode, "ndoc:method");
				int nNodes = methodNodes.Count;

				int[] indexes = SortNodesByAttribute(methodNodes, "id");

				string fileName = ctx._nameResolver.GetFilenameForMethodList(ctx.CurrentAssemblyName, typeID);
				ctx.htmlHelp.AddFileToContents("Methods", fileName);

				XsltArgumentList arguments = new XsltArgumentList();
				arguments.AddParam("type-id", String.Empty, typeID);
				arguments.AddParam("member-type", String.Empty, "method");
				TransformAndWriteResult(ctx, "individualmembers", arguments, fileName);

				ctx.htmlHelp.OpenBookInContents();

				for (int i = 0; i < nNodes; i++) {
					XmlNode methodNode = methodNodes[indexes[i]];
					string methodDisplayName = GetNodeDisplayName(methodNode);
					string methodName = GetNodeName(methodNode);
					string methodID = GetNodeId(methodNode);

					if (IsMethodFirstOverload(methodNodes, indexes, i)) {
						bOverloaded = true;

						fileName = ctx._nameResolver.GetFilenameForMethodOverloads(ctx.CurrentAssemblyName, typeID, methodName);
						ctx.htmlHelp.AddFileToContents(methodDisplayName + " Method", fileName);

						arguments = new XsltArgumentList();
						arguments.AddParam("member-id", String.Empty, methodID);
						TransformAndWriteResult(ctx, "memberoverload", arguments, fileName);

						ctx.htmlHelp.OpenBookInContents();
					}

					if (XmlUtils.GetAttributeString(methodNode, "declaringType", false) == null) {
						fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, methodID);

						string pageTitle;
						if (bOverloaded) {
							XmlNodeList parameterNodes = ctx.SelectNodes(methodNode, "ndoc:parameter");
							pageTitle = methodDisplayName + GetParamList(parameterNodes) + " Method ";
						} else {
							pageTitle = methodDisplayName + " Method";
						}
						ctx.htmlHelp.AddFileToContents(pageTitle, fileName,
							HtmlHelpIcon.Page);

						XsltArgumentList arguments2 = new XsltArgumentList();
						arguments2.AddParam("member-id", String.Empty, methodID);
						TransformAndWriteResult(ctx, "member", arguments2, fileName);
					}

					if (bOverloaded && IsMethodLastOverload(methodNodes, indexes, i)) {
						bOverloaded = false;
						ctx.htmlHelp.CloseBookInContents();
					}
				}

				ctx.htmlHelp.CloseBookInContents();
			}
		}

		private void MakeHtmlForOperators(BuildAssemblyContext ctx, XmlNode typeNode)
		{
			XmlNodeList opNodes = ctx.SelectNodes(typeNode, "ndoc:operator");

			if (opNodes.Count == 0)
				return;

			string typeID = GetNodeId(typeNode);
			string fileName = ctx._nameResolver.GetFilenameForOperatorList(ctx.CurrentAssemblyName, typeID);
			bool bOverloaded = false;

			bool bHasOperators =
				(ctx.SelectSingleNode(typeNode, "ndoc:operator[@name != 'op_Explicit' and @name != 'op_Implicit']") != null);
			bool bHasConverters =
				(ctx.SelectSingleNode(typeNode, "ndoc:operator[@name  = 'op_Explicit' or  @name  = 'op_Implicit']") != null);
			string pageTitle = "";

			if (bHasOperators) {
				pageTitle = bHasConverters ? "Operators and Type Conversions" : "Operators";
			} else {
				if (bHasConverters) {
					pageTitle = "Type Conversions";
				}
			}

			ctx.htmlHelp.AddFileToContents(pageTitle, fileName);

			XsltArgumentList arguments = new XsltArgumentList();
			arguments.AddParam("type-id", String.Empty, typeID);
			arguments.AddParam("member-type", String.Empty, "operator");
			TransformAndWriteResult(ctx, "individualmembers", arguments, fileName);

			ctx.htmlHelp.OpenBookInContents();

			int[] indexes = SortNodesByAttribute(opNodes, "id");
			int nNodes = opNodes.Count;

			//operators first
			for (int i = 0; i < nNodes; i++) {
				XmlNode operatorNode = opNodes[indexes[i]];

				string operatorID = GetNodeId(operatorNode);
				string opName = GetNodeName(operatorNode);
				if ((opName != "op_Implicit") && (opName != "op_Explicit")) {
					if (IsMethodFirstOverload(opNodes, indexes, i)) {
						bOverloaded = true;

						fileName = ctx._nameResolver.GetFilenameForOperatorOverloads(ctx.CurrentAssemblyName, typeID, opName);
						ctx.htmlHelp.AddFileToContents(GetOperatorDisplayName(ctx, operatorNode), fileName);

						arguments = new XsltArgumentList();
						arguments.AddParam("member-id", String.Empty, operatorID);
						TransformAndWriteResult(ctx, "memberoverload", arguments, fileName);

						ctx.htmlHelp.OpenBookInContents();
					}


					fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, operatorID);
					string opPageTitle;
					if (bOverloaded) {
						XmlNodeList parameterNodes = ctx.SelectNodes(operatorNode, "ns:parameter");
						opPageTitle = GetOperatorDisplayName(ctx, operatorNode) + GetParamList(parameterNodes);
					} else {
						opPageTitle = GetOperatorDisplayName(ctx, operatorNode);
					}
					ctx.htmlHelp.AddFileToContents(opPageTitle, fileName,
												   HtmlHelpIcon.Page);

					arguments = new XsltArgumentList();
					arguments.AddParam("member-id", String.Empty, operatorID);
					TransformAndWriteResult(ctx, "member", arguments, fileName);

					if (bOverloaded && IsMethodLastOverload(opNodes, indexes, i)) {
						bOverloaded = false;
						ctx.htmlHelp.CloseBookInContents();
					}
				}
			}

			//type converters
			for (int i = 0; i < nNodes; i++) {
				XmlNode operatorNode = opNodes[indexes[i]];
				string operatorID = GetNodeId(operatorNode);
				string opName = GetNodeName(operatorNode);

				if ((opName == "op_Implicit") || (opName == "op_Explicit")) {
					fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, operatorID);
					ctx.htmlHelp.AddFileToContents(GetOperatorDisplayName(ctx, operatorNode), fileName,
												   HtmlHelpIcon.Page);

					arguments = new XsltArgumentList();
					arguments.AddParam("member-id", String.Empty, operatorID);
					TransformAndWriteResult(ctx, "member", arguments, fileName);
				}
			}

			ctx.htmlHelp.CloseBookInContents();
		}

		private static string GetOperatorDisplayName(BuildProjectContext ctx, XmlNode operatorNode)
		{
			string name = GetNodeName(operatorNode);

			switch (name) {
				case "op_Decrement":
					return "Decrement Operator";
				case "op_Increment":
					return "Increment Operator";
				case "op_UnaryNegation":
					return "Unary Negation Operator";
				case "op_UnaryPlus":
					return "Unary Plus Operator";
				case "op_LogicalNot":
					return "Logical Not Operator";
				case "op_True":
					return "True Operator";
				case "op_False":
					return "False Operator";
				case "op_AddressOf":
					return "Address Of Operator";
				case "op_OnesComplement":
					return "Ones Complement Operator";
				case "op_PointerDereference":
					return "Pointer Dereference Operator";
				case "op_Addition":
					return "Addition Operator";
				case "op_Subtraction":
					return "Subtraction Operator";
				case "op_Multiply":
					return "Multiplication Operator";
				case "op_Division":
					return "Division Operator";
				case "op_Modulus":
					return "Modulus Operator";
				case "op_ExclusiveOr":
					return "Exclusive Or Operator";
				case "op_BitwiseAnd":
					return "Bitwise And Operator";
				case "op_BitwiseOr":
					return "Bitwise Or Operator";
				case "op_LogicalAnd":
					return "LogicalAnd Operator";
				case "op_LogicalOr":
					return "Logical Or Operator";
				case "op_Assign":
					return "Assignment Operator";
				case "op_LeftShift":
					return "Left Shift Operator";
				case "op_RightShift":
					return "Right Shift Operator";
				case "op_SignedRightShift":
					return "Signed Right Shift Operator";
				case "op_UnsignedRightShift":
					return "Unsigned Right Shift Operator";
				case "op_Equality":
					return "Equality Operator";
				case "op_GreaterThan":
					return "Greater Than Operator";
				case "op_LessThan":
					return "Less Than Operator";
				case "op_Inequality":
					return "Inequality Operator";
				case "op_GreaterThanOrEqual":
					return "Greater Than Or Equal Operator";
				case "op_LessThanOrEqual":
					return "Less Than Or Equal Operator";
				case "op_UnsignedRightShiftAssignment":
					return "Unsigned Right Shift Assignment Operator";
				case "op_MemberSelection":
					return "Member Selection Operator";
				case "op_RightShiftAssignment":
					return "Right Shift Assignment Operator";
				case "op_MultiplicationAssignment":
					return "Multiplication Assignment Operator";
				case "op_PointerToMemberSelection":
					return "Pointer To Member Selection Operator";
				case "op_SubtractionAssignment":
					return "Subtraction Assignment Operator";
				case "op_ExclusiveOrAssignment":
					return "Exclusive Or Assignment Operator";
				case "op_LeftShiftAssignment":
					return "Left Shift Assignment Operator";
				case "op_ModulusAssignment":
					return "Modulus Assignment Operator";
				case "op_AdditionAssignment":
					return "Addition Assignment Operator";
				case "op_BitwiseAndAssignment":
					return "Bitwise And Assignment Operator";
				case "op_BitwiseOrAssignment":
					return "Bitwise Or Assignment Operator";
				case "op_Comma":
					return "Comma Operator";
				case "op_DivisionAssignment":
					return "Division Assignment Operator";
				case "op_Explicit": {
						XmlNode parameterNode = ctx.SelectSingleNode(operatorNode, "ndoc:parameter");
						string from = GetNodeTypeId(parameterNode);
						string to = GetNodeTypeId(ctx.SelectSingleNode(operatorNode, "ndoc:returnType"));
						return "Explicit " + StripNamespace(from) + " to " + StripNamespace(to) + " Conversion";
					}
				case "op_Implicit": {
						XmlNode parameterNode = ctx.SelectSingleNode(operatorNode, "ndoc:parameter");
						string from = GetNodeTypeId(parameterNode);
						string to = GetNodeTypeId(ctx.SelectSingleNode(operatorNode, "ndoc:returnType"));
						return "Implicit " + StripNamespace(from) + " to " + StripNamespace(to) + " Conversion";
					}
				default:
					return "ERROR";
			}
		}

		private void MakeHtmlForEvents(BuildAssemblyContext ctx, XmlNode typeNode)
		{
			XmlNodeList declaredEventNodes = ctx.SelectNodes(typeNode, "ndoc:event[not(@declaringType)]");

			if (declaredEventNodes.Count > 0) {
				XmlNodeList events = ctx.SelectNodes(typeNode, "ns:event");

				if (events.Count > 0) {
					//string typeName = (string)typeNode.Attributes["name"].Value;
					string typeID = GetNodeId(typeNode);
					string fileName = ctx._nameResolver.GetFilenameForEventList(ctx.CurrentAssemblyName, typeID);

					ctx.htmlHelp.AddFileToContents("Events", fileName);

					XsltArgumentList arguments = new XsltArgumentList();
					arguments.AddParam("type-id", String.Empty, typeID);
					arguments.AddParam("member-type", String.Empty, "event");
					TransformAndWriteResult(ctx, "individualmembers", arguments, fileName);

					ctx.htmlHelp.OpenBookInContents();

					int[] indexes = SortNodesByAttribute(events, "id");

					foreach (int index in indexes) {
						XmlNode eventElement = events[index];

						if (XmlUtils.GetAttributeString(eventElement, "declaringType", false) == null) {
							string eventName = GetNodeName(eventElement);
							string eventID = GetNodeId(eventElement);

							fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, eventID);
							ctx.htmlHelp.AddFileToContents(eventName + " Event",
								fileName,
								HtmlHelpIcon.Page);

							arguments = new XsltArgumentList();
							arguments.AddParam("event-id", String.Empty, eventID);
							TransformAndWriteResult(ctx, "event", arguments, fileName);
						}
					}

					ctx.htmlHelp.CloseBookInContents();
				}
			}
		}

		private static string GetParamList(XmlNodeList parameterNodes)
		{
			ArrayList parameters = new ArrayList();

			foreach (XmlNode parameterNode in parameterNodes) {

				string parameterTypeName = GetParameterTypeName(parameterNode, "displayName");
				
				parameters.Add(parameterTypeName);
			}

			string[] parameterTypeNames = (string[]) parameters.ToArray(typeof (string));
			string paramList = "(" + string.Join(",", parameterTypeNames) + ")";

			return paramList;
		}

		private static string GetParameterTypeName(XmlNode root, string typeAttributeName)
		{
			XmlAttribute typeAtt = root.Attributes[typeAttributeName];
			return typeAtt.Value;
		}

		private static string GetNodeId(XmlNode node)
		{
			return XmlUtils.GetNodeId(node);
		}

		private static string GetNodeTypeId(XmlNode node)
		{
			return XmlUtils.GetNodeTypeId(node);
		}

		private static string GetNodeName(XmlNode node)
		{
			return XmlUtils.GetNodeName(node);
		}

		private static string GetNodeDisplayName(XmlNode node)
		{
			return XmlUtils.GetNodeDisplayName(node);
		}

		private static string StripNamespace(string name)
		{
			string result = name;

			int lastDot = name.LastIndexOf('.');

			if (lastDot != -1) {
				result = name.Substring(lastDot + 1);
			}

			return result;
		}

		private static int[] SortNodesByAttribute(XmlNodeList nodes, string attributeName)
		{
			int length = nodes.Count;
			string[] names = new string[length];
			int[] indexes = new int[length];
			int i = 0;

			foreach (XmlNode node in nodes) {
				names[i] = node.Attributes[attributeName].Value;
				indexes[i] = i++;
			}

			Array.Sort(names, indexes);

			return indexes;
		}

		private static string[] SortNamespaces(BuildProjectContext ctx, IList<string> assemblyNames, string defaultNamespace)
		{
			NameValueCollection namespaceAssemblies = new NameValueCollection();
			int nNodes = assemblyNames.Count;
			for (int i = 0; i < nNodes; i++) {
				string assemblyName = assemblyNames[i];
				GetNamespacesFromAssembly(ctx, assemblyName, namespaceAssemblies);
			}

			string[] namespaces = namespaceAssemblies.AllKeys;
			if (string.IsNullOrEmpty(defaultNamespace)) {
				Array.Sort(namespaces);
			} else {
				Array.Sort(namespaces, (x, y) =>
				{
					if (x == y) {
						return 0;
					} else if (x == null || x == defaultNamespace) {
						return -1;
					} else if (y == defaultNamespace) {
						return 1;
					}
					return x.CompareTo(y);
				});
			}
			return namespaces;
		}

		private void TransformAndWriteResult(BuildAssemblyContext ctx,
			string transformName,
			XsltArgumentList arguments,
			string filename)
		{
			Trace.WriteLine(filename);
#if DEBUG
			int start = Environment.TickCount;
#endif

			ExternalHtmlProvider htmlProvider = new ExternalHtmlProvider(MyConfig, filename);

			try {

				StreamWriter streamWriter;
				string fullPath = Path.Combine(ctx.WorkingDirectory.FullName, filename);
				using (streamWriter = new StreamWriter(
					File.Open(fullPath, FileMode.Create),
					ctx.CurrentFileEncoding)) {
					string DocLangCode = Enum.GetName(typeof(SdkLanguage), MyConfig.SdkDocLanguage).Replace("_", "-");
					
					MsdnXsltUtilities utilities = new MsdnXsltUtilities(ctx._nameResolver, ctx.CurrentAssemblyName, MyConfig.SdkDocVersionString, DocLangCode, MyConfig.SdkLinksOnWeb, ctx.CurrentFileEncoding);
					ctx._nameResolver.utilities = utilities;

					if (arguments.GetParam("assembly-name", string.Empty) == null) {
						arguments.AddParam("assembly-name", String.Empty, ctx.CurrentAssemblyName);
					}
					arguments.AddParam("ndoc-title", String.Empty, MyConfig.Title);
					arguments.AddParam("ndoc-vb-syntax", String.Empty, MyConfig.ShowVisualBasic);
					arguments.AddParam("ndoc-omit-object-tags", String.Empty, ((MyConfig.OutputTarget & OutputType.HtmlHelp) == 0));
					arguments.AddParam("ndoc-document-attributes", String.Empty, MyConfig.DocumentAttributes);
					arguments.AddParam("ndoc-documented-attributes", String.Empty, MyConfig.DocumentedAttributes);

					arguments.AddParam("ndoc-sdk-doc-base-url", String.Empty, utilities.SdkDocBaseUrl);
					arguments.AddParam("ndoc-sdk-doc-file-ext", String.Empty, utilities.SdkDocExt);
					arguments.AddParam("ndoc-sdk-doc-language", String.Empty, utilities.SdkDocLanguage);

					arguments.AddExtensionObject("urn:NDocUtil", utilities);
					arguments.AddExtensionObject("urn:NDocExternalHtml", htmlProvider);

					//Use new overload so we don't get obsolete warnings - clean compile :)

					XslTransform(ctx, transformName, ctx.GetXPathNavigable(), arguments, streamWriter, fullPath);
				}
			}
			catch(IOException ex)
			{
				throw new DocumenterException(string.Format("IO error while creating file {0}", filename), ex);
			}
//			catch (PathTooLongException e) {
//				throw new PathTooLongException(e.Message + "\nThe file that NDoc3 was trying to create had the following name:\n" + Path.Combine(ctx.WorkingDirectory.FullName, filename));
//			}

#if DEBUG
			Debug.WriteLine((Environment.TickCount - start) + " msec.");
#endif
			ctx.htmlHelp.AddFileToProject(filename);
		}
	}
}
Added Externals/NDoc3/src/NameResolver.cs.









































































































































































































































































































































































































































































































































































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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Xml;
using NDoc3.Core;
using NDoc3.Xml;

namespace NDoc3.Documenter.Msdn {
	///<summary>
	///</summary>
	public class NameResolver {
		public const string EXT = ".html";

		public MsdnXsltUtilities utilities;
		private readonly bool mergeAssemblies;
		private readonly StringDictionary fileNames = new StringDictionary();
		private readonly StringDictionary elemNames = new StringDictionary();

		private readonly ReferenceTypeDictionary<string, string[]> assemblyReferences = new ReferenceTypeDictionary<string, string[]>();

		///<summary>
		///</summary>
		///<param name="documentation"></param>
		///<param name="mergeAssemblies"></param>
		public NameResolver(XmlDocument documentation, bool mergeAssemblies) {
			this.mergeAssemblies = mergeAssemblies;
			BuildNameTables(documentation, mergeAssemblies);
		}

		#region Used for Html file generation

		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<returns></returns>
		public string GetFilenameForFieldList(string assemblyName, string typeID) {
			return GetFilenameForIdSpecial(assemblyName, typeID, "~Fields");
		}

		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<returns></returns>
		public string GetFilenameForOperatorList(string assemblyName, string typeID) {
			return GetFilenameForIdSpecial(assemblyName, typeID, "~Operators");
		}

		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<returns></returns>
		public string GetFilenameForMethodList(string assemblyName, string typeID) {
			return GetFilenameForIdSpecial(assemblyName, typeID, "~Methods");
		}

		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<returns></returns>
		public string GetFilenameForPropertyList(string assemblyName, string typeID) {
			return GetFilenameForIdSpecial(assemblyName, typeID, "~Properties");
		}

		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<returns></returns>
		public string GetFilenameForEventList(string assemblyName, string typeID) {
			return GetFilenameForIdSpecial(assemblyName, typeID, "~Events");
		}
		#endregion

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="currentAssemblyName"></param>
		///<param name="memberId"></param>
		///<returns></returns>
		public string GetDisplayNameForId(string currentAssemblyName, string memberId) {
			string name = elemNames[currentAssemblyName + memberId];
			if (name == null) {
				// search for identifier in referenced assemblies
				string[] assemblyReference = assemblyReferences[currentAssemblyName];
				if (assemblyReference != null) {
					foreach (string assemblyName in assemblyReference) {
						name = elemNames[assemblyName + memberId];
						if (name != null)
							break;
					}
				}
			}

			if (name == null) {
				name = elemNames[memberId];
			}
			return name;
		}

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="currentAssemblyName"></param>
		///<param name="memberId"></param>
		///<returns></returns>
		public string GetFilenameForId(string currentAssemblyName, string memberId) {
			// lookup current assembly
			string filename = GetFilenameForIdInternal(currentAssemblyName, memberId);
			return filename;
		}

		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<returns></returns>
		public string GetFilenameForAssembly(string assemblyName) {
			return GetFilenameForId(assemblyName, null);
		}

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="namespaceName"></param>
		///<returns></returns>
		public string GetFilenameForNamespaceHierarchy(string assemblyName, string namespaceName) {
			return GetFilenameForIdSpecial(assemblyName, "N:" + namespaceName, "~Hierarchy");
		}

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="namespaceName"></param>
		///<returns></returns>
		public string GetFilenameForNamespace(string assemblyName, string namespaceName) {
			if (mergeAssemblies)
				assemblyName = string.Empty;
			if (string.IsNullOrEmpty(namespaceName))
				namespaceName = "(global)";
			return GetFilenameForId(assemblyName, "N:" + namespaceName);
		}

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<returns></returns>
		public string GetFilenameForTypeHierarchy(string assemblyName, string typeID) {
			return GetFilenameForIdSpecial(assemblyName, typeID, "~Hierarchy");
		}

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<returns></returns>
		public string GetFilenameForTypeMemberList(string assemblyName, string typeID) {
			return GetFilenameForIdSpecial(assemblyName, typeID, "~Members");
		}

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<returns></returns>
		public string GetFilenameForConstructorList(string assemblyName, string typeID) {
			return GetFilenameForIdSpecial(assemblyName, typeID, "~Constructors");
		}

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<param name="operatorName"></param>
		///<returns></returns>
		public string GetFilenameForOperatorOverloads(string assemblyName, string typeID, string operatorName) {
			return GetFilenameForIdSpecial(assemblyName, typeID, "." + operatorName.Replace('`', '$') + "~Overloads");
		}

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<param name="propertyName"></param>
		///<returns></returns>
		public string GetFilenameForPropertyOverloads(string assemblyName, string typeID, string propertyName) {
			string fileName = GetFilenameForIdSpecial(assemblyName, typeID, "." + propertyName.Replace('`', '$') + "~Overloads");
			return fileName;
		}

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="assemblyName"></param>
		///<param name="typeID"></param>
		///<param name="methodName"></param>
		///<returns></returns>
		public string GetFilenameForMethodOverloads(string assemblyName, string typeID, string methodName) {
			string fileName = GetFilenameForIdSpecial(assemblyName, typeID, "." + methodName.Replace('`', '$').Replace("<", "(").Replace(">", ")") + "~Overloads");
			return fileName;
		}

		// exposed to XSLT
		///<summary>
		///</summary>
		///<param name="currentAssemblyName"></param>
		///<param name="typeName"></param>
		///<returns></returns>
		public string GetFilenameForTypename(string currentAssemblyName, string typeName) {

			// strip leading type identifier
			if (typeName.Length > 1 && typeName[1] != ':')
				typeName = "T:" + typeName;
			string filename = GetFilenameForId(currentAssemblyName, typeName);
			return filename;
		}

		// exposed
		///<summary>
		///</summary>
		///<param name="currentAssemblyName"></param>
		///<param name="cref"></param>
		///<param name="overload"></param>
		///<returns></returns>
		public string GetFilenameForCRefOverload(string currentAssemblyName, string cref, string overload) {
			// lookup current assembly
			string filename = GetFilenameForId(currentAssemblyName, cref);
			return filename;

			#region Original XSLT Logic
			/*
					<!--<xsl:choose>
						<xsl:when test="starts-with($cref, 'T:')">
							<xsl:call-template name="get-filename-for-type-name">
								<xsl:with-param name="type-name" select="substring-after($cref, 'T:')" />
							</xsl:call-template>
						</xsl:when>
						<xsl:when test="starts-with($cref, 'M:')">
							<xsl:choose>
								<xsl:when test="contains($cref, '.#c')">
									<xsl:value-of select="concat(translate(substring-after(substring-before($cref, '.#c'), 'M:'), '[,]', ''), 'Constructor', $overload, '.html')" />
								</xsl:when>
								<xsl:when test="contains($cref, '(')">
									<xsl:choose>
										<xsl:when test="string-length($overload) &gt; 0">
											<xsl:value-of select="concat(translate(substring-after(substring-before($cref, '('), 'M:'), '[,]', ''), '_overload_', $overload, '.html')" />
										</xsl:when>
										<xsl:otherwise>
											<xsl:value-of select="concat(translate(substring-after(substring-before($cref, '('), 'M:'), '[,]', ''), '.html')" />
										</xsl:otherwise>
									</xsl:choose>
								</xsl:when>
								<xsl:otherwise>
									<xsl:choose>
										<xsl:when test="string-length($overload) &gt; 0">
											<xsl:value-of select="concat(translate(substring-after($cref, 'M:'), '[,]', ''), '_overload_', $overload, '.html')" />
										</xsl:when>
										<xsl:otherwise>
											<xsl:value-of select="concat(translate(substring-after($cref, 'M:'), '[,]', ''), '.html')" />
										</xsl:otherwise>
									</xsl:choose>
								</xsl:otherwise>
							</xsl:choose>
						</xsl:when>
						<xsl:when test="starts-with($cref, 'E:')">
							<xsl:value-of select="concat(translate(substring-after($cref, 'E:'), '[,]', ''), $overload, '.html')" />
						</xsl:when>
						<xsl:when test="starts-with($cref, 'F:')">
							<xsl:variable name="enum" select="/ndoc/assembly/module/namespace//enumeration[field/@id = $cref]" />
							<xsl:choose>
								<xsl:when test="$enum">
									<xsl:call-template name="get-filename-for-type-name">
										<xsl:with-param name="type-name" select="substring-after($enum/@id, 'T:')" />
									</xsl:call-template>
								</xsl:when>
								<xsl:otherwise>
									<xsl:value-of select="concat(translate(substring-after($cref, 'F:'), '[,]', ''), $overload, '.html')" />
								</xsl:otherwise>
							</xsl:choose>
						</xsl:when>
						<xsl:when test="starts-with($cref, 'P:')">
							<xsl:choose>
								<xsl:when test="contains($cref, '(')">
									<xsl:value-of select="concat(translate(substring-after(substring-before($cref, '('), 'P:'), '[,]', ''), $overload, '.html')" />
								</xsl:when>
								<xsl:otherwise>
									<xsl:value-of select="concat(translate(substring-after($cref, 'P:'), '[,]', ''), $overload, '.html')" />
								</xsl:otherwise>
							</xsl:choose>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="$cref" />
						</xsl:otherwise>
					</xsl:choose>-->
			*/
			#endregion
		}

		#region BuildNameTables

		private void BuildNameTables(XmlDocument xmlDocumentation, bool mergeNamespaces) {
			XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDocumentation.NameTable);
			nsmgr.AddNamespace("ns", "urn:ndoc-schema");
			XmlNodeList assemblies = xmlDocumentation.SelectNodes("/ns:ndoc/ns:assembly", nsmgr);
			if(assemblies == null) throw new Exception("No assemblies found");
			foreach (XmlElement assemblyNode in assemblies) {
				string assemblyName = GetNodeName(assemblyNode);
				RegisterAssembly(assemblyName);

				// build list of assemblyReferences
				XmlNodeList assemblyReferenceNodes = assemblyNode.SelectNodes("ns:assemblyReference", nsmgr);
				if(assemblyReferenceNodes == null) throw new Exception("No assembly reference nodes found");
				List<string> assemblyReferenceNames = new List<string>();
				foreach (XmlNode assemblyReferenceNode in assemblyReferenceNodes) {
					assemblyReferenceNames.Add(GetNodeName(assemblyReferenceNode));
				}
				assemblyReferences.Add(assemblyName, assemblyReferenceNames.ToArray());

				// foreach namespace
				XmlNodeList namespaces = assemblyNode.SelectNodes("ns:module/ns:namespace", nsmgr);
				if(namespaces == null) throw new Exception("No namespaces found");
				foreach (XmlElement namespaceNode in namespaces) {
					string namespaceName = GetNodeName(namespaceNode);
					// register namespace
					RegisterNamespace((mergeNamespaces ? string.Empty : assemblyName), namespaceName);

					XmlNodeList types = namespaceNode.SelectNodes("*[@id]", nsmgr);
					if(types == null) throw new Exception("No types found");
					foreach (XmlElement typeNode in types) {
						string typeId = GetNodeId(typeNode);
						//TODO The rest should also use displayName ((EE): clarify what above line means - shall we remove 'name' attribute then?)
						string typeDisplayName = GetNodeDisplayName(typeNode);
						RegisterType(assemblyName, typeId, typeDisplayName);

						// foreach member
						XmlNodeList members = typeNode.SelectNodes("*[@id]");
						if(members == null) throw new Exception("No type members found");
						foreach (XmlElement memberNode in members) {
							string memberId = GetNodeId(memberNode);
							switch (memberNode.Name) {
								case "constructor": {
									string overload = XmlUtils.GetAttributeString(memberNode, "overload", false);
										RegisterConstructor(assemblyName, typeId, memberId, overload);
									}
									break;
								case "field": {
										bool isEnum = (typeNode.Name == "enumeration");
										string memberName = GetNodeName(memberNode);
										RegisterField(assemblyName, typeId, memberId, isEnum, memberName);
									}
									break;
								case "property": {
										string overload = GetNodeOverload(memberNode);
										string memberName = GetNodeName(memberNode);
										RegisterProperty(assemblyName, memberId, memberName, overload);
									}
									break;
								case "method": {
										string overload = GetNodeOverload(memberNode);
										string memberDisplayName = GetNodeDisplayName(memberNode);
										RegisterMethod(assemblyName, memberId, memberDisplayName, overload);
									}
									break;
								case "operator": {
										string overload = GetNodeOverload(memberNode);
										string memberName = GetNodeName(memberNode);
										RegisterOperator(assemblyName, memberId, memberName, overload);
									}
									break;
								case "event": {
										string memberName = GetNodeName(memberNode);
										RegisterEvent(assemblyName, memberId, memberName);
									}
									break;
							}
						}
					}
				}
			}
		}

		private void RegisterAssembly(string assemblyName) {
			Register(assemblyName, null, assemblyName, CalculateFilenameForId(assemblyName, null, null));
		}

		private void RegisterNamespace(string assemblyName, string namespaceName) {
			if (string.IsNullOrEmpty(namespaceName)) {
				namespaceName = "(global)";
			}
			string namespaceId = "N:" + namespaceName;
			Register(assemblyName, namespaceId, namespaceName, CalculateFilenameForId(assemblyName, namespaceId, null));
		}

		private void RegisterType(string assemblyName, string typeId, string displayName) {
			Register(assemblyName, typeId, displayName, CalculateFilenameForId(assemblyName, typeId, null));
		}

		private void RegisterConstructor(string assemblyName, string typeId, string id, string overload) {
			Register(assemblyName, id, GetDisplayNameForId(assemblyName, typeId), CalculateFilenameForId(assemblyName, id, overload));
		}

		private void RegisterOperator(string assemblyName, string memberId, string memberName, string overload) {
			Register(assemblyName, memberId, memberName, CalculateFilenameForId(assemblyName, memberId, overload));
		}

		private void RegisterMethod(string assemblyName, string memberId, string memberDisplayName, string overload) {
			Register(assemblyName, memberId, memberDisplayName, CalculateFilenameForId(assemblyName, memberId, overload));
		}

		private void RegisterProperty(string assemblyName, string memberId, string memberName, string overload) {
			Register(assemblyName, memberId, memberName, CalculateFilenameForId(assemblyName, memberId, overload));
		}

		private void RegisterField(string assemblyName, string typeId, string memberId, bool isEnum, string memberName) {
			if (isEnum) {
				Register(assemblyName, memberId, memberName, GetFilenameForId(assemblyName, typeId));
			} else {
				Register(assemblyName, memberId, memberName, CalculateFilenameForId(assemblyName, memberId, null));
			}
		}

		private void RegisterEvent(string assemblyName, string memberId, string memberName) {
			Register(assemblyName, memberId, memberName, CalculateFilenameForId(assemblyName, memberId, null));
		}


		#endregion

		#region Registration & Lookup Logic

		private string GetFilenameForIdInternal(string currentAssemblyName, string memberId) {
			string filename = fileNames[currentAssemblyName + memberId];
			if (filename == null) {
				// search for identifier in referenced assemblies
				string[] assemblyReference = assemblyReferences[currentAssemblyName];
				if (assemblyReference != null) {
					foreach (string assemblyName in assemblyReference) {
						filename = fileNames[assemblyName + memberId];
						if (filename != null)
							break;
					}
				}
			}

			if (filename == null && memberId != null) {
				filename = fileNames[memberId];
			}

			//			Debug.Assert(filename != null, string.Format("Filename for assembly:memberId [{0}:{1}] not found", currentAssemblyName, memberId));
			//			Debug.WriteLine(string.Format("GetFilenameForIdInternal('{0}','{1}') => {2}", currentAssemblyName, memberId, filename));
			if (filename != null)
				return filename;

			if (utilities != null)
			{
				if (memberId.Length > 2 && memberId[1] == ':')
					memberId = memberId.Substring(2);

				filename = utilities.FormatOnlineSDKLink(memberId);

				if (filename != null)
					return filename;
			}

			return String.Empty;
		}

		private string GetFilenameForIdSpecial(string assemblyName, string memberId, string postfix) {
			string fn = GetFilenameForIdInternal(assemblyName, memberId);
			if (fn != null && fn.Length > EXT.Length) {
				fn = fn.Insert(fn.Length - EXT.Length, postfix);
			}
			//			Debug.WriteLine(string.Format("GetFilenameForIdSpecial('{0}','{1}') => {2}", assemblyName, memberId, fn));
			return fn;
		}

		private void Register(string assemblyName, string id, string displayName, string fileName) {
			//			Debug.WriteLine(string.Format("Registering [{0},{1}]=[{2},{3}]", assemblyName, id, displayName, fileName));
			fileNames[assemblyName + id] = fileName;
			elemNames[assemblyName + id] = displayName;
		}

		/// <summary>
		/// of the form "T:XXX", "F:XXX" etc
		/// </summary>
		private static string CalculateFilenameForId(string assemblyName, string id, string overload) {
			if (id == null) {
				return assemblyName + EXT;
			}

			//			char idType = '\0';
			int ix = id.IndexOf(':');
			//			if (ix > -1) {
			//				idType = id[0];
			//			}
			id = id.Substring(ix + 1);

			// constructors could be #ctor or #cctor
			//			int ixDotHash = id.IndexOf(".#c"); 
			//			if (ixDotHash > -1)
			//				id = id.Substring(0, ixDotHash);

			// methods could have "("
			int ixLBrace = id.IndexOf("(");
			if (ixLBrace > -1)
				id = id.Substring(0, ixLBrace);

			if (overload != null) {
				id += overload;
			}

			id = id.Replace('#', '~');
			// generic methods have the form "methodname<Arg1, Arg2, ...>"
			id = id.Replace('<', '{');
			id = id.Replace('>', '}');

			id = id.Replace('`', '$');
			return assemblyName + "~" + id + EXT;
		}

		#endregion

		#region Xml Utility Methods

		private static string GetNodeOverload(XmlNode memberNode) {
			return XmlUtils.GetAttributeString(memberNode, "overload", false);
		}

		private static string GetNodeId(XmlNode node) {
			return XmlUtils.GetNodeId(node);
		}

		private static string GetNodeName(XmlNode node) {
			return XmlUtils.GetNodeName(node);
		}

		private static string GetNodeDisplayName(XmlNode node) {
			return XmlUtils.GetNodeDisplayName(node);
		}

		#endregion
	}
}
Changes to SQLite.Beta.nuspec.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

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

14
15
16
17
18
19
20
21













-
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Beta.nuspec -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<package>
  <metadata>
    <id>System.Data.SQLite.Beta</id>
    <title>System.Data.SQLite (x86/x64) Beta</title>
    <version>1.0.89.0</version>
    <version>1.0.90.0</version>
    <authors>SQLite Development Team</authors>
    <description>The official SQLite database engine for both x86 and x64 along with the ADO.NET provider.</description>
    <language>en-US</language>
    <projectUrl>http://system.data.sqlite.org/</projectUrl>
    <iconUrl>http://system.data.sqlite.org/images/sqlite32.png</iconUrl>
    <licenseUrl>http://www.sqlite.org/copyright.html</licenseUrl>
    <tags>sqlite database ado.net provider interop</tags>
Changes to SQLite.Designer/AssemblyInfo.cs.
39
40
41
42
43
44
45
46
47


39
40
41
42
43
44
45


46
47







-
-
+
+
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.89.0")]
[assembly: AssemblyFileVersion("1.0.89.0")]
[assembly: AssemblyVersion("1.0.90.0")]
[assembly: AssemblyFileVersion("1.0.90.0")]
Changes to SQLite.Designer/source.extension.vsixmanifest.
1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







<?xml version="1.0" encoding="utf-8"?>
<Vsix Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
  <Identifier Id="67b5f3a9-cde1-430f-a12b-af95bb064851">
    <Name>System.Data.SQLite Designer</Name>
    <Author>http://system.data.sqlite.org/</Author>
    <Version>1.0.89.0</Version>
    <Version>1.0.90.0</Version>
    <Description>ADO.NET Data Designer for SQLite</Description>
    <Locale>1033</Locale>
    <InstalledByMsi>false</InstalledByMsi>
    <SupportedProducts>
      <VisualStudio Version="10.0">
        <Edition>Pro</Edition>
      </VisualStudio>
Changes to SQLite.Interop/SQLite.Interop.2005.vcproj.
947
948
949
950
951
952
953








































































































































954
955
956
957
958
959
960
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
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
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096







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







						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\contrib\extension-functions.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\regexp.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\totype.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
Changes to SQLite.Interop/SQLite.Interop.2008.vcproj.
947
948
949
950
951
952
953








































































































































954
955
956
957
958
959
960
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
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
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096







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







						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\contrib\extension-functions.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\regexp.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\totype.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
Changes to SQLite.Interop/SQLite.Interop.2010.vcxproj.
473
474
475
476
477
478
479






480
481
482
483
484
485
486
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492







+
+
+
+
+
+







    </ClCompile>
    <ClCompile Include="src\win\crypt.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\contrib\extension-functions.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\regexp.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\totype.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\vtshim.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\win\interop.c" />
    <ClCompile Include="src\core\sqlite3.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
Changes to SQLite.Interop/SQLite.Interop.2010.vcxproj.filters.
30
31
32
33
34
35
36






37
38
39
40
41
42
43
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49







+
+
+
+
+
+







      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\win\crypt.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\contrib\extension-functions.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\regexp.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\totype.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\vtshim.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\win\interop.c">
      <Filter>Source Files</Filter>
    </ClCompile>
Changes to SQLite.Interop/SQLite.Interop.2012.vcxproj.
480
481
482
483
484
485
486






487
488
489
490
491
492
493
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499







+
+
+
+
+
+







    </ClCompile>
    <ClCompile Include="src\win\crypt.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\contrib\extension-functions.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\regexp.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\totype.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\vtshim.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\win\interop.c" />
    <ClCompile Include="src\core\sqlite3.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
Changes to SQLite.Interop/SQLite.Interop.2012.vcxproj.filters.
30
31
32
33
34
35
36






37
38
39
40
41
42
43
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49







+
+
+
+
+
+







      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\win\crypt.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\contrib\extension-functions.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\regexp.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\totype.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\vtshim.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\win\interop.c">
      <Filter>Source Files</Filter>
    </ClCompile>
Changes to SQLite.Interop/SQLite.Interop.CE.2005.vcproj.
733
734
735
736
737
738
739








































































































740
741
742
743
744
745
746
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850







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







						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\contrib\extension-functions.c"
				>
				<FileConfiguration
					Name="Debug|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\regexp.c"
				>
				<FileConfiguration
					Name="Debug|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\totype.c"
				>
				<FileConfiguration
					Name="Debug|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
Changes to SQLite.Interop/SQLite.Interop.CE.2008.vcproj.
733
734
735
736
737
738
739








































































































740
741
742
743
744
745
746
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850







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







						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\contrib\extension-functions.c"
				>
				<FileConfiguration
					Name="Debug|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\regexp.c"
				>
				<FileConfiguration
					Name="Debug|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\totype.c"
				>
				<FileConfiguration
					Name="Debug|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
Changes to SQLite.Interop/SQLite.Interop.Static.2005.vcproj.
947
948
949
950
951
952
953








































































































































954
955
956
957
958
959
960
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
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
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096







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







						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\contrib\extension-functions.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\regexp.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\totype.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
Changes to SQLite.Interop/SQLite.Interop.Static.2008.vcproj.
947
948
949
950
951
952
953








































































































































954
955
956
957
958
959
960
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
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
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096







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







						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\contrib\extension-functions.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\regexp.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="DebugNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="ReleaseNativeOnly|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\ext\totype.c"
				>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
Changes to SQLite.Interop/SQLite.Interop.Static.2010.vcxproj.
473
474
475
476
477
478
479






480
481
482
483
484
485
486
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492







+
+
+
+
+
+







    </ClCompile>
    <ClCompile Include="src\win\crypt.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\contrib\extension-functions.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\regexp.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\totype.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\vtshim.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\win\interop.c" />
    <ClCompile Include="src\core\sqlite3.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
Changes to SQLite.Interop/SQLite.Interop.Static.2010.vcxproj.filters.
30
31
32
33
34
35
36






37
38
39
40
41
42
43
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49







+
+
+
+
+
+







      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\win\crypt.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\contrib\extension-functions.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\regexp.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\totype.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\vtshim.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\win\interop.c">
      <Filter>Source Files</Filter>
    </ClCompile>
Changes to SQLite.Interop/SQLite.Interop.Static.2012.vcxproj.
480
481
482
483
484
485
486






487
488
489
490
491
492
493
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499







+
+
+
+
+
+







    </ClCompile>
    <ClCompile Include="src\win\crypt.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\contrib\extension-functions.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\regexp.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\totype.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\ext\vtshim.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="src\win\interop.c" />
    <ClCompile Include="src\core\sqlite3.c">
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </ClCompile>
Changes to SQLite.Interop/SQLite.Interop.Static.2012.vcxproj.filters.
30
31
32
33
34
35
36






37
38
39
40
41
42
43
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49







+
+
+
+
+
+







      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\win\crypt.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\contrib\extension-functions.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\regexp.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\totype.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\ext\vtshim.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\win\interop.c">
      <Filter>Source Files</Filter>
    </ClCompile>
Changes to SQLite.Interop/props/SQLite.Interop.2005.vsprops.
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
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







-
+









-
+




-
+







	<UserMacro
		Name="ConfigurationYear"
		Value="2005"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_BUILD_NUMBER"
		Value="089"
		Value="090"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_LINKER_VERSION"
		Value="1.0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_MANIFEST_VERSION"
		Value="1.0.89.0"
		Value="1.0.90.0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_RC_VERSION"
		Value="1,0,89,0"
		Value="1,0,90,0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_INCLUDE_DIRECTORIES"
		Value="src\core"
		PerformEnvironmentSet="true"
	/>
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69







-
+







	<UserMacro
		Name="INTEROP_DEBUG_DEFINES"
		Value="INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_EXTRA_DEFINES"
		Value="INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1"
		Value="INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1;INTEROP_TOTYPE_EXTENSION=1;INTEROP_REGEXP_EXTENSION=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_ASSEMBLY_RESOURCES"
		Value="/ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteCommand.bmp,System.Data.SQLite.SQLiteCommand.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteConnection.bmp,System.Data.SQLite.SQLiteConnection.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteDataAdapter.bmp,System.Data.SQLite.SQLiteDataAdapter.bmp"
		PerformEnvironmentSet="true"
	/>
Changes to SQLite.Interop/props/SQLite.Interop.2008.vsprops.
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
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







-
+









-
+




-
+







	<UserMacro
		Name="ConfigurationYear"
		Value="2008"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_BUILD_NUMBER"
		Value="089"
		Value="090"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_LINKER_VERSION"
		Value="1.0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_MANIFEST_VERSION"
		Value="1.0.89.0"
		Value="1.0.90.0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_RC_VERSION"
		Value="1,0,89,0"
		Value="1,0,90,0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_INCLUDE_DIRECTORIES"
		Value="src\core"
		PerformEnvironmentSet="true"
	/>
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69







-
+







	<UserMacro
		Name="INTEROP_DEBUG_DEFINES"
		Value="INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_EXTRA_DEFINES"
		Value="INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1"
		Value="INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1;INTEROP_TOTYPE_EXTENSION=1;INTEROP_REGEXP_EXTENSION=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_ASSEMBLY_RESOURCES"
		Value="/ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteCommand.bmp,System.Data.SQLite.SQLiteCommand.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteConnection.bmp,System.Data.SQLite.SQLiteConnection.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteDataAdapter.bmp,System.Data.SQLite.SQLiteDataAdapter.bmp"
		PerformEnvironmentSet="true"
	/>
Changes to SQLite.Interop/props/SQLite.Interop.2010.props.
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
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












-
+

-
-
+
+




-
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.2010.props -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup Label="UserMacros">
    <ConfigurationYear>2010</ConfigurationYear>
    <INTEROP_BUILD_NUMBER>089</INTEROP_BUILD_NUMBER>
    <INTEROP_BUILD_NUMBER>090</INTEROP_BUILD_NUMBER>
    <INTEROP_LINKER_VERSION>1.0</INTEROP_LINKER_VERSION>
    <INTEROP_MANIFEST_VERSION>1.0.89.0</INTEROP_MANIFEST_VERSION>
    <INTEROP_RC_VERSION>1,0,89,0</INTEROP_RC_VERSION>
    <INTEROP_MANIFEST_VERSION>1.0.90.0</INTEROP_MANIFEST_VERSION>
    <INTEROP_RC_VERSION>1,0,90,0</INTEROP_RC_VERSION>
    <INTEROP_INCLUDE_DIRECTORIES>src\core</INTEROP_INCLUDE_DIRECTORIES>
    <INTEROP_LIBRARY_DIRECTORIES></INTEROP_LIBRARY_DIRECTORIES>
    <INTEROP_LIBRARY_DEPENDENCIES></INTEROP_LIBRARY_DEPENDENCIES>
    <INTEROP_DEBUG_DEFINES>INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1</INTEROP_DEBUG_DEFINES>
    <INTEROP_EXTRA_DEFINES>INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1</INTEROP_EXTRA_DEFINES>
    <INTEROP_EXTRA_DEFINES>INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1;INTEROP_TOTYPE_EXTENSION=1;INTEROP_REGEXP_EXTENSION=1</INTEROP_EXTRA_DEFINES>
    <INTEROP_ASSEMBLY_RESOURCES>/ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteCommand.bmp,System.Data.SQLite.SQLiteCommand.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteConnection.bmp,System.Data.SQLite.SQLiteConnection.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteDataAdapter.bmp,System.Data.SQLite.SQLiteDataAdapter.bmp</INTEROP_ASSEMBLY_RESOURCES>
    <INTEROP_KEY_FILE>$(ProjectDir)..\System.Data.SQLite\System.Data.SQLite.snk</INTEROP_KEY_FILE>
    <INTEROP_NATIVE_NAME>SQLite.Interop</INTEROP_NATIVE_NAME>
    <INTEROP_MIXED_NAME>System.Data.SQLite</INTEROP_MIXED_NAME>
  </PropertyGroup>
  <ItemGroup>
    <BuildMacro Include="ConfigurationYear">
Changes to SQLite.Interop/props/SQLite.Interop.2012.props.
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
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












-
+

-
-
+
+




-
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.2012.props -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup Label="UserMacros">
    <ConfigurationYear>2012</ConfigurationYear>
    <INTEROP_BUILD_NUMBER>089</INTEROP_BUILD_NUMBER>
    <INTEROP_BUILD_NUMBER>090</INTEROP_BUILD_NUMBER>
    <INTEROP_LINKER_VERSION>1.0</INTEROP_LINKER_VERSION>
    <INTEROP_MANIFEST_VERSION>1.0.89.0</INTEROP_MANIFEST_VERSION>
    <INTEROP_RC_VERSION>1,0,89,0</INTEROP_RC_VERSION>
    <INTEROP_MANIFEST_VERSION>1.0.90.0</INTEROP_MANIFEST_VERSION>
    <INTEROP_RC_VERSION>1,0,90,0</INTEROP_RC_VERSION>
    <INTEROP_INCLUDE_DIRECTORIES>src\core</INTEROP_INCLUDE_DIRECTORIES>
    <INTEROP_LIBRARY_DIRECTORIES></INTEROP_LIBRARY_DIRECTORIES>
    <INTEROP_LIBRARY_DEPENDENCIES></INTEROP_LIBRARY_DEPENDENCIES>
    <INTEROP_DEBUG_DEFINES>INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1</INTEROP_DEBUG_DEFINES>
    <INTEROP_EXTRA_DEFINES>INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1</INTEROP_EXTRA_DEFINES>
    <INTEROP_EXTRA_DEFINES>INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1;INTEROP_TOTYPE_EXTENSION=1;INTEROP_REGEXP_EXTENSION=1</INTEROP_EXTRA_DEFINES>
    <INTEROP_ASSEMBLY_RESOURCES>/ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteCommand.bmp,System.Data.SQLite.SQLiteCommand.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteConnection.bmp,System.Data.SQLite.SQLiteConnection.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteDataAdapter.bmp,System.Data.SQLite.SQLiteDataAdapter.bmp</INTEROP_ASSEMBLY_RESOURCES>
    <INTEROP_KEY_FILE>$(ProjectDir)..\System.Data.SQLite\System.Data.SQLite.snk</INTEROP_KEY_FILE>
    <INTEROP_NATIVE_NAME>SQLite.Interop</INTEROP_NATIVE_NAME>
    <INTEROP_MIXED_NAME>System.Data.SQLite</INTEROP_MIXED_NAME>
  </PropertyGroup>
  <ItemGroup>
    <BuildMacro Include="ConfigurationYear">
Changes to SQLite.Interop/props/sqlite3.props.
1
2
3
4
5
6
7
8
9
10
11
12
13
14



15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11



12
13
14
15
16
17
18
19
20
21











-
-
-
+
+
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * sqlite3.props -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup Label="UserMacros">
    <SQLITE_MANIFEST_VERSION>3.8.1</SQLITE_MANIFEST_VERSION>
    <SQLITE_RC_VERSION>3,8,1</SQLITE_RC_VERSION>
    <SQLITE_COMMON_DEFINES>_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;SQLITE_THREADSAFE=1;SQLITE_USE_URI=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT4=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1</SQLITE_COMMON_DEFINES>
    <SQLITE_MANIFEST_VERSION>3.8.2</SQLITE_MANIFEST_VERSION>
    <SQLITE_RC_VERSION>3,8,2</SQLITE_RC_VERSION>
    <SQLITE_COMMON_DEFINES>_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;SQLITE_THREADSAFE=1;SQLITE_USE_URI=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT4=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1;SQLITE_ENABLE_MEMORY_MANAGEMENT=1</SQLITE_COMMON_DEFINES>
    <SQLITE_EXTRA_DEFINES>SQLITE_HAS_CODEC=1</SQLITE_EXTRA_DEFINES>
    <SQLITE_WINCE_DEFINES>SQLITE_OMIT_WAL=1</SQLITE_WINCE_DEFINES>
    <SQLITE_DEBUG_DEFINES>SQLITE_DEBUG=1;SQLITE_MEMDEBUG=1;SQLITE_ENABLE_EXPENSIVE_ASSERT=1</SQLITE_DEBUG_DEFINES>
    <SQLITE_RELEASE_DEFINES>SQLITE_WIN32_MALLOC=1</SQLITE_RELEASE_DEFINES>
    <SQLITE_DISABLE_WARNINGS>4055;4100;4127;4146;4210;4232;4244;4245;4267;4306;4389;4701;4703;4706</SQLITE_DISABLE_WARNINGS>
    <SQLITE_DISABLE_X64_WARNINGS></SQLITE_DISABLE_X64_WARNINGS>
  </PropertyGroup>
Changes to SQLite.Interop/props/sqlite3.vsprops.
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
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







-
+




-
+




-
+







<VisualStudioPropertySheet
	ProjectType="Visual C++"
	Version="8.00"
	Name="sqlite3"
	>
	<UserMacro
		Name="SQLITE_MANIFEST_VERSION"
		Value="3.8.1"
		Value="3.8.2"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_RC_VERSION"
		Value="3,8,1"
		Value="3,8,2"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_COMMON_DEFINES"
		Value="_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;SQLITE_THREADSAFE=1;SQLITE_USE_URI=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT4=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1"
		Value="_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;SQLITE_THREADSAFE=1;SQLITE_USE_URI=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT4=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1;SQLITE_ENABLE_MEMORY_MANAGEMENT=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_EXTRA_DEFINES"
		Value="SQLITE_HAS_CODEC=1"
		PerformEnvironmentSet="true"
	/>
Changes to SQLite.Interop/src/core/sqlite3.c.

more than 10,000 changes

Changes to SQLite.Interop/src/core/sqlite3.h.
103
104
105
106
107
108
109
110
111
112



113
114
115
116
117
118
119
103
104
105
106
107
108
109



110
111
112
113
114
115
116
117
118
119







-
-
-
+
+
+







** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.1"
#define SQLITE_VERSION_NUMBER 3008001
#define SQLITE_SOURCE_ID      "2013-09-12 02:09:05 75a8a8c1b39725d36db627536d0c69401f8e0815"
#define SQLITE_VERSION        "3.8.2"
#define SQLITE_VERSION_NUMBER 3008002
#define SQLITE_SOURCE_ID      "2013-11-11 19:56:35 f58d57017199421167dae8ebc67db2f19be45082"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
497
498
499
500
501
502
503

504
505
506
507
508
509
510
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511







+







#define SQLITE_CONSTRAINT_FOREIGNKEY   (SQLITE_CONSTRAINT | (3<<8))
#define SQLITE_CONSTRAINT_FUNCTION     (SQLITE_CONSTRAINT | (4<<8))
#define SQLITE_CONSTRAINT_NOTNULL      (SQLITE_CONSTRAINT | (5<<8))
#define SQLITE_CONSTRAINT_PRIMARYKEY   (SQLITE_CONSTRAINT | (6<<8))
#define SQLITE_CONSTRAINT_TRIGGER      (SQLITE_CONSTRAINT | (7<<8))
#define SQLITE_CONSTRAINT_UNIQUE       (SQLITE_CONSTRAINT | (8<<8))
#define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
#define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
#define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))

/*
** CAPI3REF: Flags For File Open Operations
**
908
909
910
911
912
913
914








915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933

934
935
936
937
938
939
940
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950







+
+
+
+
+
+
+
+



















+







** The argument is a pointer to a value of type sqlite3_int64 that
** is an advisory maximum number of bytes in the file to memory map.  The
** pointer is overwritten with the old value.  The limit is not changed if
** the value originally pointed to is negative, and so the current limit 
** can be queried by passing in a pointer to a negative number.  This
** file-control is used internally to implement [PRAGMA mmap_size].
**
** <li>[[SQLITE_FCNTL_TRACE]]
** The [SQLITE_FCNTL_TRACE] file control provides advisory information
** to the VFS about what the higher layers of the SQLite stack are doing.
** This file control is used by some VFS activity tracing [shims].
** The argument is a zero-terminated string.  Higher layers in the
** SQLite stack may generate instances of this file control if
** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
**
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE               1
#define SQLITE_GET_LOCKPROXYFILE             2
#define SQLITE_SET_LOCKPROXYFILE             3
#define SQLITE_LAST_ERRNO                    4
#define SQLITE_FCNTL_SIZE_HINT               5
#define SQLITE_FCNTL_CHUNK_SIZE              6
#define SQLITE_FCNTL_FILE_POINTER            7
#define SQLITE_FCNTL_SYNC_OMITTED            8
#define SQLITE_FCNTL_WIN32_AV_RETRY          9
#define SQLITE_FCNTL_PERSIST_WAL            10
#define SQLITE_FCNTL_OVERWRITE              11
#define SQLITE_FCNTL_VFSNAME                12
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
#define SQLITE_FCNTL_PRAGMA                 14
#define SQLITE_FCNTL_BUSYHANDLER            15
#define SQLITE_FCNTL_TEMPFILENAME           16
#define SQLITE_FCNTL_MMAP_SIZE              18
#define SQLITE_FCNTL_TRACE                  19

/*
** CAPI3REF: Mutex Handle
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
** abstract type for a mutex object.  The SQLite core never looks
** at the internal representation of an [sqlite3_mutex].  It only
1613
1614
1615
1616
1617
1618
1619
1620

1621
1622

1623
1624
1625
1626

1627
1628

1629
1630

1631
1632
1633

1634
1635

1636
1637
1638
1639
1640

1641
1642
1643
1644
1645
1646
1647
1623
1624
1625
1626
1627
1628
1629

1630
1631

1632
1633
1634
1635

1636
1637

1638
1639

1640
1641
1642

1643
1644

1645
1646
1647
1648
1649

1650
1651
1652
1653
1654
1655
1656
1657







-
+

-
+



-
+

-
+

-
+


-
+

-
+




-
+







** log message after formatting via [sqlite3_snprintf()].
** The SQLite logging interface is not reentrant; the logger function
** supplied by the application must not invoke any SQLite interface.
** In a multi-threaded application, the application-defined logger
** function must be threadsafe. </dd>
**
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
** <dd> This option takes a single argument of type int. If non-zero, then
** <dd>^(This option takes a single argument of type int. If non-zero, then
** URI handling is globally enabled. If the parameter is zero, then URI handling
** is globally disabled. If URI handling is globally enabled, all filenames
** is globally disabled.)^ ^If URI handling is globally enabled, all filenames
** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
** connection is opened. If it is globally disabled, filenames are
** connection is opened. ^If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
** database connection is opened. By default, URI handling is globally
** database connection is opened. ^(By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined.
** [SQLITE_USE_URI] symbol defined.)^
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd> This option takes a single integer argument which is interpreted as
** <dd>^This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for
** full table scans in the query optimizer.  The default setting is determined
** full table scans in the query optimizer.  ^The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** malfunction when the optimization is enabled.  Providing the ability to
** when the optimization is enabled.  Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
**
** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
** <dd> These options are obsolete and should not be used by new code.
** They are retained for backwards compatibility but are now no-ops.
1662
1663
1664
1665
1666
1667
1668
1669

1670
1671
1672

1673
1674

1675
1676
1677
1678


1679
1680
1681
1682
1683
1684
1685
1672
1673
1674
1675
1676
1677
1678

1679
1680
1681

1682
1683

1684
1685
1686


1687
1688
1689
1690
1691
1692
1693
1694
1695







-
+


-
+

-
+


-
-
+
+







** the connection being passed as the second parameter is being closed. The
** third parameter is passed NULL In this case.  An example of using this
** configuration option can be seen in the "test_sqllog.c" source file in
** the canonical SQLite source tree.</dd>
**
** [[SQLITE_CONFIG_MMAP_SIZE]]
** <dt>SQLITE_CONFIG_MMAP_SIZE
** <dd>SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** that are the default mmap size limit (the default setting for
** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
** The default setting can be overridden by each database connection using
** ^The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_size] command, or by using the
** [SQLITE_FCNTL_MMAP_SIZE] file control.  The maximum allowed mmap size
** [SQLITE_FCNTL_MMAP_SIZE] file control.  ^(The maximum allowed mmap size
** cannot be changed at run-time.  Nor may the maximum allowed mmap size
** exceed the compile-time maximum mmap size set by the
** [SQLITE_MAX_MMAP_SIZE] compile-time option.  
** If either argument to this option is negative, then that argument is
** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
1773
1774
1775
1776
1777
1778
1779

1780

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







1793
1794
1795
1796
1797
1798
1799
1783
1784
1785
1786
1787
1788
1789
1790

1791
1792
1793
1794
1795
1796
1797






1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811







+
-
+






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







** codes are disabled by default for historical compatibility.
*/
SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);

/*
** CAPI3REF: Last Insert Rowid
**
** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
** ^Each entry in an SQLite table has a unique 64-bit signed
** has a unique 64-bit signed
** integer key called the [ROWID | "rowid"]. ^The rowid is always available
** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
** names are not also used by explicitly declared columns. ^If
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
** ^This routine returns the [rowid] of the most recent
** successful [INSERT] into the database from the [database connection]
** in the first argument.  ^As of SQLite version 3.7.7, this routines
** records the last insert rowid of both ordinary tables and [virtual tables].
** ^If no successful [INSERT]s
** have ever occurred on that database connection, zero is returned.
** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the 
** most recent successful [INSERT] into a rowid table or [virtual table]
** on database connection D.
** ^Inserts into [WITHOUT ROWID] tables are not recorded.
** ^If no successful [INSERT]s into rowid tables
** have ever occurred on the database connection D, 
** then sqlite3_last_insert_rowid(D) returns zero.
**
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
** method, then this routine will return the [rowid] of the inserted
** row as long as the trigger or virtual table method is running.
** But once the trigger or virtual table method ends, the value returned 
** by this routine reverts to what it was before the trigger or virtual
** table method began.)^
4802
4803
4804
4805
4806
4807
4808
4809


4810
4811
4812
4813
4814

4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826

4827
4828
4829
4830
4831
4832
4833
4814
4815
4816
4817
4818
4819
4820

4821
4822
4823
4824
4825
4826

4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847







-
+
+




-
+












+







SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);

/*
** CAPI3REF: Data Change Notification Callbacks
**
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
** to be invoked whenever a row is updated, inserted or deleted.
** to be invoked whenever a row is updated, inserted or deleted in
** a rowid table.
** ^Any callback set by a previous call to this function
** for the same database connection is overridden.
**
** ^The second argument is a pointer to the function to invoke when a
** row is updated, inserted or deleted.
** row is updated, inserted or deleted in a rowid table.
** ^The first argument to the callback is a copy of the third argument
** to sqlite3_update_hook().
** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
** or [SQLITE_UPDATE], depending on the operation that caused the callback
** to be invoked.
** ^The third and fourth arguments to the callback contain pointers to the
** database and table name containing the affected row.
** ^The final callback parameter is the [rowid] of the row.
** ^In the case of an update, this is the [rowid] after the update takes place.
**
** ^(The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).)^
** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
** is not invoked when duplication rows are deleted because of an
** [ON CONFLICT | ON CONFLICT REPLACE] clause.  ^Nor is the update hook
** invoked when rows are deleted using the [truncate optimization].
** The exceptions defined in this paragraph might change in a future
** release of SQLite.
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
















5288
5289
5290
5291
5292
5293
5294
5291
5292
5293
5294
5295
5296
5297




5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320







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







** ^[sqlite3_free()] is used to free idxPtr if and only if
** needToFreeIdxPtr is true.
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
** ^The estimatedCost value is an estimate of the cost of doing the
** particular lookup.  A full scan of a table with N entries should have
** a cost of N.  A binary search of a table of N entries should have a
** cost of approximately log(N).
** ^The estimatedCost value is an estimate of the cost of a particular
** strategy. A cost of N indicates that the cost of the strategy is similar
** to a linear scan of an SQLite table with N rows. A cost of log(N) 
** indicates that the expense of the operation is similar to that of a
** binary search on a unique indexed field of an SQLite table with N rows.
**
** ^The estimatedRows value is an estimate of the number of rows that
** will be returned by the strategy.
**
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
** structure for SQLite version 3.8.2. If a virtual table extension is
** used with an SQLite version earlier than 3.8.2, the results of attempting 
** to read or write the estimatedRows field are undefined (but are likely 
** to included crashing the application). The estimatedRows field should
** therefore only be used if [sqlite3_libversion_number()] returns a
** value greater than or equal to 3008002.
*/
struct sqlite3_index_info {
  /* Inputs */
  int nConstraint;           /* Number of entries in aConstraint */
  struct sqlite3_index_constraint {
     int iColumn;              /* Column on left-hand side of constraint */
     unsigned char op;         /* Constraint operator */
5305
5306
5307
5308
5309
5310
5311
5312


5313
5314
5315
5316
5317
5318
5319
5331
5332
5333
5334
5335
5336
5337

5338
5339
5340
5341
5342
5343
5344
5345
5346







-
+
+







    int argvIndex;           /* if >0, constraint is part of argv to xFilter */
    unsigned char omit;      /* Do not code a test for this constraint */
  } *aConstraintUsage;
  int idxNum;                /* Number used to identify the index */
  char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
  int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
  int orderByConsumed;       /* True if output is already ordered */
  double estimatedCost;      /* Estimated cost of using this index */
  double estimatedCost;           /* Estimated cost of using this index */
  sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
};

/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros defined the allowed values for the
** [sqlite3_index_info].aConstraint[].op field.  Each value represents
5509
5510
5511
5512
5513
5514
5515



5516
5517
5518
5519
5520
5521
5522
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552







+
+
+







** commit if the transaction continues to completion.)^
**
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob.  ^The size of a blob may not be changed by this
** interface.  Use the [UPDATE] SQL command to change the size of a
** blob.
**
** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
** table.  Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
**
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function can be used, if desired,
** to create an empty, zero-filled blob in which to read or write using
** this interface.
**
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
Added SQLite.Interop/src/ext/regexp.c.
























































































































































































































































































































































































































































































































































































































































































































































































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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
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
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
** 2012-11-13
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** The code in this file implements a compact but reasonably
** efficient regular-expression matcher for posix extended regular
** expressions against UTF8 text.
**
** This file is an SQLite extension.  It registers a single function
** named "regexp(A,B)" where A is the regular expression and B is the
** string to be matched.  By registering this function, SQLite will also
** then implement the "B regexp A" operator.  Note that with the function
** the regular expression comes first, but with the operator it comes
** second.
**
**  The following regular expression syntax is supported:
**
**     X*      zero or more occurrences of X
**     X+      one or more occurrences of X
**     X?      zero or one occurrences of X
**     X{p,q}  between p and q occurrences of X
**     (X)     match X
**     X|Y     X or Y
**     ^X      X occurring at the beginning of the string
**     X$      X occurring at the end of the string
**     .       Match any single character
**     \c      Character c where c is one of \{}()[]|*+?.
**     \c      C-language escapes for c in afnrtv.  ex: \t or \n
**     \uXXXX  Where XXXX is exactly 4 hex digits, unicode value XXXX
**     \xXX    Where XX is exactly 2 hex digits, unicode value XX
**     [abc]   Any single character from the set abc
**     [^abc]  Any single character not in the set abc
**     [a-z]   Any single character in the range a-z
**     [^a-z]  Any single character not in the range a-z
**     \b      Word boundary
**     \w      Word character.  [A-Za-z0-9_]
**     \W      Non-word character
**     \d      Digit
**     \D      Non-digit
**     \s      Whitespace character
**     \S      Non-whitespace character
**
** A nondeterministic finite automaton (NFA) is used for matching, so the
** performance is bounded by O(N*M) where N is the size of the regular
** expression and M is the size of the input string.  The matcher never
** exhibits exponential behavior.  Note that the X{p,q} operator expands
** to p copies of X following by q-p copies of X? and that the size of the
** regular expression in the O(N*M) performance bound is computed after
** this expansion.
*/
#include <string.h>
#include <stdlib.h>
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1

/*
** The following #defines change the names of some functions implemented in
** this file to prevent name collisions with C-library functions of the
** same name.
*/
#define re_match   sqlite3re_match
#define re_compile sqlite3re_compile
#define re_free    sqlite3re_free

/* The end-of-input character */
#define RE_EOF            0    /* End of input */

/* The NFA is implemented as sequence of opcodes taken from the following
** set.  Each opcode has a single integer argument.
*/
#define RE_OP_MATCH       1    /* Match the one character in the argument */
#define RE_OP_ANY         2    /* Match any one character.  (Implements ".") */
#define RE_OP_ANYSTAR     3    /* Special optimized version of .* */
#define RE_OP_FORK        4    /* Continue to both next and opcode at iArg */
#define RE_OP_GOTO        5    /* Jump to opcode at iArg */
#define RE_OP_ACCEPT      6    /* Halt and indicate a successful match */
#define RE_OP_CC_INC      7    /* Beginning of a [...] character class */
#define RE_OP_CC_EXC      8    /* Beginning of a [^...] character class */
#define RE_OP_CC_VALUE    9    /* Single value in a character class */
#define RE_OP_CC_RANGE   10    /* Range of values in a character class */
#define RE_OP_WORD       11    /* Perl word character [A-Za-z0-9_] */
#define RE_OP_NOTWORD    12    /* Not a perl word character */
#define RE_OP_DIGIT      13    /* digit:  [0-9] */
#define RE_OP_NOTDIGIT   14    /* Not a digit */
#define RE_OP_SPACE      15    /* space:  [ \t\n\r\v\f] */
#define RE_OP_NOTSPACE   16    /* Not a digit */
#define RE_OP_BOUNDARY   17    /* Boundary between word and non-word */

/* Each opcode is a "state" in the NFA */
typedef unsigned short ReStateNumber;

/* Because this is an NFA and not a DFA, multiple states can be active at
** once.  An instance of the following object records all active states in
** the NFA.  The implementation is optimized for the common case where the
** number of actives states is small.
*/
typedef struct ReStateSet {
  unsigned nState;            /* Number of current states */
  ReStateNumber *aState;      /* Current states */
} ReStateSet;

/* An input string read one character at a time.
*/
typedef struct ReInput ReInput;
struct ReInput {
  const unsigned char *z;  /* All text */
  int i;                   /* Next byte to read */
  int mx;                  /* EOF when i>=mx */
};

/* A compiled NFA (or an NFA that is in the process of being compiled) is
** an instance of the following object.
*/
typedef struct ReCompiled ReCompiled;
struct ReCompiled {
  ReInput sIn;                /* Regular expression text */
  const char *zErr;           /* Error message to return */
  char *aOp;                  /* Operators for the virtual machine */
  int *aArg;                  /* Arguments to each operator */
  unsigned (*xNextChar)(ReInput*);  /* Next character function */
  unsigned char zInit[12];    /* Initial text to match */
  int nInit;                  /* Number of characters in zInit */
  unsigned nState;            /* Number of entries in aOp[] and aArg[] */
  unsigned nAlloc;            /* Slots allocated for aOp[] and aArg[] */
};

/* Add a state to the given state set if it is not already there */
static void re_add_state(ReStateSet *pSet, int newState){
  unsigned i;
  for(i=0; i<pSet->nState; i++) if( pSet->aState[i]==newState ) return;
  pSet->aState[pSet->nState++] = newState;
}

/* Extract the next unicode character from *pzIn and return it.  Advance
** *pzIn to the first byte past the end of the character returned.  To
** be clear:  this routine converts utf8 to unicode.  This routine is 
** optimized for the common case where the next character is a single byte.
*/
static unsigned re_next_char(ReInput *p){
  unsigned c;
  if( p->i>=p->mx ) return 0;
  c = p->z[p->i++];
  if( c>=0x80 ){
    if( (c&0xe0)==0xc0 && p->i<p->mx && (p->z[p->i]&0xc0)==0x80 ){
      c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f);
      if( c<0x80 ) c = 0xfffd;
    }else if( (c&0xf0)==0xe0 && p->i+1<p->mx && (p->z[p->i]&0xc0)==0x80
           && (p->z[p->i+1]&0xc0)==0x80 ){
      c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
      p->i += 2;
      if( c<=0x3ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
    }else if( (c&0xf8)==0xf0 && p->i+3<p->mx && (p->z[p->i]&0xc0)==0x80
           && (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){
      c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6)
                       | (p->z[p->i+2]&0x3f);
      p->i += 3;
      if( c<=0xffff || c>0x10ffff ) c = 0xfffd;
    }else{
      c = 0xfffd;
    }
  }
  return c;
}
static unsigned re_next_char_nocase(ReInput *p){
  unsigned c = re_next_char(p);
  if( c>='A' && c<='Z' ) c += 'a' - 'A';
  return c;
}

/* Return true if c is a perl "word" character:  [A-Za-z0-9_] */
static int re_word_char(int c){
  return (c>='0' && c<='9') || (c>='a' && c<='z')
      || (c>='A' && c<='Z') || c=='_';
}

/* Return true if c is a "digit" character:  [0-9] */
static int re_digit_char(int c){
  return (c>='0' && c<='9');
}

/* Return true if c is a perl "space" character:  [ \t\r\n\v\f] */
static int re_space_char(int c){
  return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f';
}

/* Run a compiled regular expression on the zero-terminated input
** string zIn[].  Return true on a match and false if there is no match.
*/
static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
  ReStateSet aStateSet[2], *pThis, *pNext;
  ReStateNumber aSpace[100];
  ReStateNumber *pToFree;
  unsigned int i = 0;
  unsigned int iSwap = 0;
  int c = RE_EOF+1;
  int cPrev = 0;
  int rc = 0;
  ReInput in;

  in.z = zIn;
  in.i = 0;
  in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn);

  /* Look for the initial prefix match, if there is one. */
  if( pRe->nInit ){
    unsigned char x = pRe->zInit[0];
    while( in.i+pRe->nInit<=in.mx 
     && (zIn[in.i]!=x ||
         strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
    ){
      in.i++;
    }
    if( in.i+pRe->nInit>in.mx ) return 0;
  }

  if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
    pToFree = 0;
    aStateSet[0].aState = aSpace;
  }else{
    pToFree = sqlite3_malloc( sizeof(ReStateNumber)*2*pRe->nState );
    if( pToFree==0 ) return -1;
    aStateSet[0].aState = pToFree;
  }
  aStateSet[1].aState = &aStateSet[0].aState[pRe->nState];
  pNext = &aStateSet[1];
  pNext->nState = 0;
  re_add_state(pNext, 0);
  while( c!=RE_EOF && pNext->nState>0 ){
    cPrev = c;
    c = pRe->xNextChar(&in);
    pThis = pNext;
    pNext = &aStateSet[iSwap];
    iSwap = 1 - iSwap;
    pNext->nState = 0;
    for(i=0; i<pThis->nState; i++){
      int x = pThis->aState[i];
      switch( pRe->aOp[x] ){
        case RE_OP_MATCH: {
          if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_ANY: {
          re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_WORD: {
          if( re_word_char(c) ) re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_NOTWORD: {
          if( !re_word_char(c) ) re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_DIGIT: {
          if( re_digit_char(c) ) re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_NOTDIGIT: {
          if( !re_digit_char(c) ) re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_SPACE: {
          if( re_space_char(c) ) re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_NOTSPACE: {
          if( !re_space_char(c) ) re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_BOUNDARY: {
          if( re_word_char(c)!=re_word_char(cPrev) ) re_add_state(pThis, x+1);
          break;
        }
        case RE_OP_ANYSTAR: {
          re_add_state(pNext, x);
          re_add_state(pThis, x+1);
          break;
        }
        case RE_OP_FORK: {
          re_add_state(pThis, x+pRe->aArg[x]);
          re_add_state(pThis, x+1);
          break;
        }
        case RE_OP_GOTO: {
          re_add_state(pThis, x+pRe->aArg[x]);
          break;
        }
        case RE_OP_ACCEPT: {
          rc = 1;
          goto re_match_end;
        }
        case RE_OP_CC_INC:
        case RE_OP_CC_EXC: {
          int j = 1;
          int n = pRe->aArg[x];
          int hit = 0;
          for(j=1; j>0 && j<n; j++){
            if( pRe->aOp[x+j]==RE_OP_CC_VALUE ){
              if( pRe->aArg[x+j]==c ){
                hit = 1;
                j = -1;
              }
            }else{
              if( pRe->aArg[x+j]<=c && pRe->aArg[x+j+1]>=c ){
                hit = 1;
                j = -1;
              }else{
                j++;
              }
            }
          }
          if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit;
          if( hit ) re_add_state(pNext, x+n);
          break;            
        }
      }
    }
  }
  for(i=0; i<pNext->nState; i++){
    if( pRe->aOp[pNext->aState[i]]==RE_OP_ACCEPT ){ rc = 1; break; }
  }
re_match_end:
  sqlite3_free(pToFree);
  return rc;
}

/* Resize the opcode and argument arrays for an RE under construction.
*/
static int re_resize(ReCompiled *p, int N){
  char *aOp;
  int *aArg;
  aOp = sqlite3_realloc(p->aOp, N*sizeof(p->aOp[0]));
  if( aOp==0 ) return 1;
  p->aOp = aOp;
  aArg = sqlite3_realloc(p->aArg, N*sizeof(p->aArg[0]));
  if( aArg==0 ) return 1;
  p->aArg = aArg;
  p->nAlloc = N;
  return 0;
}

/* Insert a new opcode and argument into an RE under construction.  The
** insertion point is just prior to existing opcode iBefore.
*/
static int re_insert(ReCompiled *p, int iBefore, int op, int arg){
  int i;
  if( p->nAlloc<=p->nState && re_resize(p, p->nAlloc*2) ) return 0;
  for(i=p->nState; i>iBefore; i--){
    p->aOp[i] = p->aOp[i-1];
    p->aArg[i] = p->aArg[i-1];
  }
  p->nState++;
  p->aOp[iBefore] = op;
  p->aArg[iBefore] = arg;
  return iBefore;
}

/* Append a new opcode and argument to the end of the RE under construction.
*/
static int re_append(ReCompiled *p, int op, int arg){
  return re_insert(p, p->nState, op, arg);
}

/* Make a copy of N opcodes starting at iStart onto the end of the RE
** under construction.
*/
static void re_copy(ReCompiled *p, int iStart, int N){
  if( p->nState+N>=p->nAlloc && re_resize(p, p->nAlloc*2+N) ) return;
  memcpy(&p->aOp[p->nState], &p->aOp[iStart], N*sizeof(p->aOp[0]));
  memcpy(&p->aArg[p->nState], &p->aArg[iStart], N*sizeof(p->aArg[0]));
  p->nState += N;
}

/* Return true if c is a hexadecimal digit character:  [0-9a-fA-F]
** If c is a hex digit, also set *pV = (*pV)*16 + valueof(c).  If
** c is not a hex digit *pV is unchanged.
*/
static int re_hex(int c, int *pV){
  if( c>='0' && c<='9' ){
    c -= '0';
  }else if( c>='a' && c<='f' ){
    c -= 'a' - 10;
  }else if( c>='A' && c<='F' ){
    c -= 'A' - 10;
  }else{
    return 0;
  }
  *pV = (*pV)*16 + (c & 0xff);
  return 1;
}

/* A backslash character has been seen, read the next character and
** return its interpretation.
*/
static unsigned re_esc_char(ReCompiled *p){
  static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]";
  static const char zTrans[] = "\a\f\n\r\t\v";
  int i, v = 0;
  char c;
  if( p->sIn.i>=p->sIn.mx ) return 0;
  c = p->sIn.z[p->sIn.i];
  if( c=='u' && p->sIn.i+4<p->sIn.mx ){
    const unsigned char *zIn = p->sIn.z + p->sIn.i;
    if( re_hex(zIn[1],&v)
     && re_hex(zIn[2],&v)
     && re_hex(zIn[3],&v)
     && re_hex(zIn[4],&v)
    ){
      p->sIn.i += 5;
      return v;
    }
  }
  if( c=='x' && p->sIn.i+2<p->sIn.mx ){
    const unsigned char *zIn = p->sIn.z + p->sIn.i;
    if( re_hex(zIn[1],&v)
     && re_hex(zIn[2],&v)
    ){
      p->sIn.i += 3;
      return v;
    }
  }
  for(i=0; zEsc[i] && zEsc[i]!=c; i++){}
  if( zEsc[i] ){
    if( i<6 ) c = zTrans[i];
    p->sIn.i++;
  }else{
    p->zErr = "unknown \\ escape";
  }
  return c;
}

/* Forward declaration */
static const char *re_subcompile_string(ReCompiled*);

/* Peek at the next byte of input */
static unsigned char rePeek(ReCompiled *p){
  return p->sIn.i<p->sIn.mx ? p->sIn.z[p->sIn.i] : 0;
}

/* Compile RE text into a sequence of opcodes.  Continue up to the
** first unmatched ")" character, then return.  If an error is found,
** return a pointer to the error message string.
*/
static const char *re_subcompile_re(ReCompiled *p){
  const char *zErr;
  int iStart, iEnd, iGoto;
  iStart = p->nState;
  zErr = re_subcompile_string(p);
  if( zErr ) return zErr;
  while( rePeek(p)=='|' ){
    iEnd = p->nState;
    re_insert(p, iStart, RE_OP_FORK, iEnd + 2 - iStart);
    iGoto = re_append(p, RE_OP_GOTO, 0);
    p->sIn.i++;
    zErr = re_subcompile_string(p);
    if( zErr ) return zErr;
    p->aArg[iGoto] = p->nState - iGoto;
  }
  return 0;
}

/* Compile an element of regular expression text (anything that can be
** an operand to the "|" operator).  Return NULL on success or a pointer
** to the error message if there is a problem.
*/
static const char *re_subcompile_string(ReCompiled *p){
  int iPrev = -1;
  int iStart;
  unsigned c;
  const char *zErr;
  while( (c = p->xNextChar(&p->sIn))!=0 ){
    iStart = p->nState;
    switch( c ){
      case '|':
      case '$': 
      case ')': {
        p->sIn.i--;
        return 0;
      }
      case '(': {
        zErr = re_subcompile_re(p);
        if( zErr ) return zErr;
        if( rePeek(p)!=')' ) return "unmatched '('";
        p->sIn.i++;
        break;
      }
      case '.': {
        if( rePeek(p)=='*' ){
          re_append(p, RE_OP_ANYSTAR, 0);
          p->sIn.i++;
        }else{ 
          re_append(p, RE_OP_ANY, 0);
        }
        break;
      }
      case '*': {
        if( iPrev<0 ) return "'*' without operand";
        re_insert(p, iPrev, RE_OP_GOTO, p->nState - iPrev + 1);
        re_append(p, RE_OP_FORK, iPrev - p->nState + 1);
        break;
      }
      case '+': {
        if( iPrev<0 ) return "'+' without operand";
        re_append(p, RE_OP_FORK, iPrev - p->nState);
        break;
      }
      case '?': {
        if( iPrev<0 ) return "'?' without operand";
        re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
        break;
      }
      case '{': {
        int m = 0, n = 0;
        int sz, j;
        if( iPrev<0 ) return "'{m,n}' without operand";
        while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }
        n = m;
        if( c==',' ){
          p->sIn.i++;
          n = 0;
          while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }
        }
        if( c!='}' ) return "unmatched '{'";
        if( n>0 && n<m ) return "n less than m in '{m,n}'";
        p->sIn.i++;
        sz = p->nState - iPrev;
        if( m==0 ){
          if( n==0 ) return "both m and n are zero in '{m,n}'";
          re_insert(p, iPrev, RE_OP_FORK, sz+1);
          n--;
        }else{
          for(j=1; j<m; j++) re_copy(p, iPrev, sz);
        }
        for(j=m; j<n; j++){
          re_append(p, RE_OP_FORK, sz+1);
          re_copy(p, iPrev, sz);
        }
        if( n==0 && m>0 ){
          re_append(p, RE_OP_FORK, -sz);
        }
        break;
      }
      case '[': {
        int iFirst = p->nState;
        if( rePeek(p)=='^' ){
          re_append(p, RE_OP_CC_EXC, 0);
          p->sIn.i++;
        }else{
          re_append(p, RE_OP_CC_INC, 0);
        }
        while( (c = p->xNextChar(&p->sIn))!=0 ){
          if( c=='[' && rePeek(p)==':' ){
            return "POSIX character classes not supported";
          }
          if( c=='\\' ) c = re_esc_char(p);
          if( rePeek(p)=='-' ){
            re_append(p, RE_OP_CC_RANGE, c);
            p->sIn.i++;
            c = p->xNextChar(&p->sIn);
            if( c=='\\' ) c = re_esc_char(p);
            re_append(p, RE_OP_CC_RANGE, c);
          }else{
            re_append(p, RE_OP_CC_VALUE, c);
          }
          if( rePeek(p)==']' ){ p->sIn.i++; break; }
        }
        if( c==0 ) return "unclosed '['";
        p->aArg[iFirst] = p->nState - iFirst;
        break;
      }
      case '\\': {
        int specialOp = 0;
        switch( rePeek(p) ){
          case 'b': specialOp = RE_OP_BOUNDARY;   break;
          case 'd': specialOp = RE_OP_DIGIT;      break;
          case 'D': specialOp = RE_OP_NOTDIGIT;   break;
          case 's': specialOp = RE_OP_SPACE;      break;
          case 'S': specialOp = RE_OP_NOTSPACE;   break;
          case 'w': specialOp = RE_OP_WORD;       break;
          case 'W': specialOp = RE_OP_NOTWORD;    break;
        }
        if( specialOp ){
          p->sIn.i++;
          re_append(p, specialOp, 0);
        }else{
          c = re_esc_char(p);
          re_append(p, RE_OP_MATCH, c);
        }
        break;
      }
      default: {
        re_append(p, RE_OP_MATCH, c);
        break;
      }
    }
    iPrev = iStart;
  }
  return 0;
}

/* Free and reclaim all the memory used by a previously compiled
** regular expression.  Applications should invoke this routine once
** for every call to re_compile() to avoid memory leaks.
*/
void re_free(ReCompiled *pRe){
  if( pRe ){
    sqlite3_free(pRe->aOp);
    sqlite3_free(pRe->aArg);
    sqlite3_free(pRe);
  }
}

/*
** Compile a textual regular expression in zIn[] into a compiled regular
** expression suitable for us by re_match() and return a pointer to the
** compiled regular expression in *ppRe.  Return NULL on success or an
** error message if something goes wrong.
*/
const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
  ReCompiled *pRe;
  const char *zErr;
  int i, j;

  *ppRe = 0;
  pRe = sqlite3_malloc( sizeof(*pRe) );
  if( pRe==0 ){
    return "out of memory";
  }
  memset(pRe, 0, sizeof(*pRe));
  pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char;
  if( re_resize(pRe, 30) ){
    re_free(pRe);
    return "out of memory";
  }
  if( zIn[0]=='^' ){
    zIn++;
  }else{
    re_append(pRe, RE_OP_ANYSTAR, 0);
  }
  pRe->sIn.z = (unsigned char*)zIn;
  pRe->sIn.i = 0;
  pRe->sIn.mx = (int)strlen(zIn);
  zErr = re_subcompile_re(pRe);
  if( zErr ){
    re_free(pRe);
    return zErr;
  }
  if( rePeek(pRe)=='$' && pRe->sIn.i+1>=pRe->sIn.mx ){
    re_append(pRe, RE_OP_MATCH, RE_EOF);
    re_append(pRe, RE_OP_ACCEPT, 0);
    *ppRe = pRe;
  }else if( pRe->sIn.i>=pRe->sIn.mx ){
    re_append(pRe, RE_OP_ACCEPT, 0);
    *ppRe = pRe;
  }else{
    re_free(pRe);
    return "unrecognized character";
  }

  /* The following is a performance optimization.  If the regex begins with
  ** ".*" (if the input regex lacks an initial "^") and afterwards there are
  ** one or more matching characters, enter those matching characters into
  ** zInit[].  The re_match() routine can then search ahead in the input 
  ** string looking for the initial match without having to run the whole
  ** regex engine over the string.  Do not worry able trying to match
  ** unicode characters beyond plane 0 - those are very rare and this is
  ** just an optimization. */
  if( pRe->aOp[0]==RE_OP_ANYSTAR ){
    for(j=0, i=1; j<sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
      unsigned x = pRe->aArg[i];
      if( x<=127 ){
        pRe->zInit[j++] = x;
      }else if( x<=0xfff ){
        pRe->zInit[j++] = 0xc0 | (x>>6);
        pRe->zInit[j++] = 0x80 | (x&0x3f);
      }else if( x<=0xffff ){
        pRe->zInit[j++] = 0xd0 | (x>>12);
        pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
        pRe->zInit[j++] = 0x80 | (x&0x3f);
      }else{
        break;
      }
    }
    if( j>0 && pRe->zInit[j-1]==0 ) j--;
    pRe->nInit = j;
  }
  return pRe->zErr;
}

/*
** Implementation of the regexp() SQL function.  This function implements
** the build-in REGEXP operator.  The first argument to the function is the
** pattern and the second argument is the string.  So, the SQL statements:
**
**       A REGEXP B
**
** is implemented as regexp(B,A).
*/
static void re_sql_func(
  sqlite3_context *context, 
  int argc, 
  sqlite3_value **argv
){
  ReCompiled *pRe;          /* Compiled regular expression */
  const char *zPattern;     /* The regular expression */
  const unsigned char *zStr;/* String being searched */
  const char *zErr;         /* Compile error message */
  int setAux = 0;           /* True to invoke sqlite3_set_auxdata() */

  pRe = sqlite3_get_auxdata(context, 0);
  if( pRe==0 ){
    zPattern = (const char*)sqlite3_value_text(argv[0]);
    if( zPattern==0 ) return;
    zErr = re_compile(&pRe, zPattern, 0);
    if( zErr ){
      re_free(pRe);
      sqlite3_result_error(context, zErr, -1);
      return;
    }
    if( pRe==0 ){
      sqlite3_result_error_nomem(context);
      return;
    }
    setAux = 1;
  }
  zStr = (const unsigned char*)sqlite3_value_text(argv[1]);
  if( zStr!=0 ){
    sqlite3_result_int(context, re_match(pRe, zStr, -1));
  }
  if( setAux ){
    sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free);
  }
}

/*
** Invoke this routine to register the regexp() function with the
** SQLite database connection.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_regexp_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, 0,
                                 re_sql_func, 0, 0);
  return rc;
}
Added SQLite.Interop/src/ext/totype.c.
































































































































































































































































































































































































































































































































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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
** 2013-10-14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This SQLite extension implements functions tointeger(X) and toreal(X).
**
** If X is an integer, real, or string value that can be
** losslessly represented as an integer, then tointeger(X)
** returns the corresponding integer value.
** If X is an 8-byte BLOB then that blob is interpreted as
** a signed two-compliment little-endian encoding of an integer
** and tointeger(X) returns the corresponding integer value.
** Otherwise tointeger(X) return NULL.
**
** If X is an integer, real, or string value that can be
** convert into a real number, preserving at least 15 digits
** of precision, then toreal(X) returns the corresponding real value.
** If X is an 8-byte BLOB then that blob is interpreted as
** a 64-bit IEEE754 big-endian floating point value
** and toreal(X) returns the corresponding real value.
** Otherwise toreal(X) return NULL.
**
** Note that tointeger(X) of an 8-byte BLOB assumes a little-endian
** encoding whereas toreal(X) of an 8-byte BLOB assumes a big-endian
** encoding.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>

/*
** Determine if this is running on a big-endian or little-endian
** processor
*/
#if defined(i386) || defined(__i386__) || defined(_M_IX86)\
                             || defined(__x86_64) || defined(__x86_64__)
# define TOTYPE_BIGENDIAN    0
# define TOTYPE_LITTLEENDIAN 1
#else
  const int totype_one = 1;
# define TOTYPE_BIGENDIAN    (*(char *)(&totype_one)==0)
# define TOTYPE_LITTLEENDIAN (*(char *)(&totype_one)==1)
#endif

/*
** Constants for the largest and smallest possible 64-bit signed integers.
** These macros are designed to work correctly on both 32-bit and 64-bit
** compilers.
*/
#ifndef LARGEST_INT64
# define LARGEST_INT64   (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
#endif

#ifndef SMALLEST_INT64
# define SMALLEST_INT64  (((sqlite3_int64)-1) - LARGEST_INT64)
#endif

/*
** Return TRUE if character c is a whitespace character
*/
static int totypeIsspace(unsigned char c){
  return c==' ' || c=='\t' || c=='\n' || c=='\v' || c=='\f' || c=='\r';
}

/*
** Return TRUE if character c is a digit
*/
static int totypeIsdigit(unsigned char c){
  return c>='0' && c<='9';
}

/*
** Compare the 19-character string zNum against the text representation
** value 2^63:  9223372036854775808.  Return negative, zero, or positive
** if zNum is less than, equal to, or greater than the string.
** Note that zNum must contain exactly 19 characters.
**
** Unlike memcmp() this routine is guaranteed to return the difference
** in the values of the last digit if the only difference is in the
** last digit.  So, for example,
**
**      totypeCompare2pow63("9223372036854775800")
**
** will return -8.
*/
static int totypeCompare2pow63(const char *zNum){
  int c = 0;
  int i;
                    /* 012345678901234567 */
  const char *pow63 = "922337203685477580";
  for(i=0; c==0 && i<18; i++){
    c = (zNum[i]-pow63[i])*10;
  }
  if( c==0 ){
    c = zNum[18] - '8';
  }
  return c;
}

/*
** Convert zNum to a 64-bit signed integer.
**
** If the zNum value is representable as a 64-bit twos-complement
** integer, then write that value into *pNum and return 0.
**
** If zNum is exactly 9223372036854665808, return 2.  This special
** case is broken out because while 9223372036854665808 cannot be a
** signed 64-bit integer, its negative -9223372036854665808 can be.
**
** If zNum is too big for a 64-bit integer and is not
** 9223372036854665808  or if zNum contains any non-numeric text,
** then return 1.
**
** The string is not necessarily zero-terminated.
*/
static int totypeAtoi64(const char *zNum, sqlite3_int64 *pNum, int length){
  sqlite3_uint64 u = 0;
  int neg = 0; /* assume positive */
  int i;
  int c = 0;
  int nonNum = 0;
  const char *zStart;
  const char *zEnd = zNum + length;

  while( zNum<zEnd && totypeIsspace(*zNum) ) zNum++;
  if( zNum<zEnd ){
    if( *zNum=='-' ){
      neg = 1;
      zNum++;
    }else if( *zNum=='+' ){
      zNum++;
    }
  }
  zStart = zNum;
  while( zNum<zEnd && zNum[0]=='0' ){ zNum++; } /* Skip leading zeros. */
  for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i++){
    u = u*10 + c - '0';
  }
  if( u>LARGEST_INT64 ){
    *pNum = SMALLEST_INT64;
  }else if( neg ){
    *pNum = -(sqlite3_int64)u;
  }else{
    *pNum = (sqlite3_int64)u;
  }
  if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19 || nonNum ){
    /* zNum is empty or contains non-numeric text or is longer
    ** than 19 digits (thus guaranteeing that it is too large) */
    return 1;
  }else if( i<19 ){
    /* Less than 19 digits, so we know that it fits in 64 bits */
    assert( u<=LARGEST_INT64 );
    return 0;
  }else{
    /* zNum is a 19-digit numbers.  Compare it against 9223372036854775808. */
    c = totypeCompare2pow63(zNum);
    if( c<0 ){
      /* zNum is less than 9223372036854775808 so it fits */
      assert( u<=LARGEST_INT64 );
      return 0;
    }else if( c>0 ){
      /* zNum is greater than 9223372036854775808 so it overflows */
      return 1;
    }else{
      /* zNum is exactly 9223372036854775808.  Fits if negative.  The
      ** special case 2 overflow if positive */
      assert( u-1==LARGEST_INT64 );
      assert( (*pNum)==SMALLEST_INT64 );
      return neg ? 0 : 2;
    }
  }
}

/*
** The string z[] is an text representation of a real number.
** Convert this string to a double and write it into *pResult.
**
** The string is not necessarily zero-terminated.
**
** Return TRUE if the result is a valid real number (or integer) and FALSE
** if the string is empty or contains extraneous text.  Valid numbers
** are in one of these formats:
**
**    [+-]digits[E[+-]digits]
**    [+-]digits.[digits][E[+-]digits]
**    [+-].digits[E[+-]digits]
**
** Leading and trailing whitespace is ignored for the purpose of determining
** validity.
**
** If some prefix of the input string is a valid number, this routine
** returns FALSE but it still converts the prefix and writes the result
** into *pResult.
*/
static int totypeAtoF(const char *z, double *pResult, int length){
  const char *zEnd = z + length;
  /* sign * significand * (10 ^ (esign * exponent)) */
  int sign = 1;    /* sign of significand */
  sqlite3_int64 s = 0;       /* significand */
  int d = 0;       /* adjust exponent for shifting decimal point */
  int esign = 1;   /* sign of exponent */
  int e = 0;       /* exponent */
  int eValid = 1;  /* True exponent is either not used or is well-formed */
  double result;
  int nDigits = 0;
  int nonNum = 0;

  *pResult = 0.0;   /* Default return value, in case of an error */

  /* skip leading spaces */
  while( z<zEnd && totypeIsspace(*z) ) z++;
  if( z>=zEnd ) return 0;

  /* get sign of significand */
  if( *z=='-' ){
    sign = -1;
    z++;
  }else if( *z=='+' ){
    z++;
  }

  /* skip leading zeroes */
  while( z<zEnd && z[0]=='0' ) z++, nDigits++;

  /* copy max significant digits to significand */
  while( z<zEnd && totypeIsdigit(*z) && s<((LARGEST_INT64-9)/10) ){
    s = s*10 + (*z - '0');
    z++, nDigits++;
  }

  /* skip non-significant significand digits
  ** (increase exponent by d to shift decimal left) */
  while( z<zEnd && totypeIsdigit(*z) ) z++, nDigits++, d++;
  if( z>=zEnd ) goto totype_atof_calc;

  /* if decimal point is present */
  if( *z=='.' ){
    z++;
    /* copy digits from after decimal to significand
    ** (decrease exponent by d to shift decimal right) */
    while( z<zEnd && totypeIsdigit(*z) && s<((LARGEST_INT64-9)/10) ){
      s = s*10 + (*z - '0');
      z++, nDigits++, d--;
    }
    /* skip non-significant digits */
    while( z<zEnd && totypeIsdigit(*z) ) z++, nDigits++;
  }
  if( z>=zEnd ) goto totype_atof_calc;

  /* if exponent is present */
  if( *z=='e' || *z=='E' ){
    z++;
    eValid = 0;
    if( z>=zEnd ) goto totype_atof_calc;
    /* get sign of exponent */
    if( *z=='-' ){
      esign = -1;
      z++;
    }else if( *z=='+' ){
      z++;
    }
    /* copy digits to exponent */
    while( z<zEnd && totypeIsdigit(*z) ){
      e = e<10000 ? (e*10 + (*z - '0')) : 10000;
      z++;
      eValid = 1;
    }
  }

  /* skip trailing spaces */
  if( nDigits && eValid ){
    while( z<zEnd && totypeIsspace(*z) ) z++;
  }

totype_atof_calc:
  /* adjust exponent by d, and update sign */
  e = (e*esign) + d;
  if( e<0 ) {
    esign = -1;
    e *= -1;
  } else {
    esign = 1;
  }

  /* if 0 significand */
  if( !s ) {
    /* In the IEEE 754 standard, zero is signed.
    ** Add the sign if we've seen at least one digit */
    result = (sign<0 && nDigits) ? -(double)0 : (double)0;
  } else {
    /* attempt to reduce exponent */
    if( esign>0 ){
      while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
    }else{
      while( !(s%10) && e>0 ) e--,s/=10;
    }

    /* adjust the sign of significand */
    s = sign<0 ? -s : s;

    /* if exponent, scale significand as appropriate
    ** and store in result. */
    if( e ){
      double scale = 1.0;
      /* attempt to handle extremely small/large numbers better */
      if( e>307 && e<342 ){
        while( e%308 ) { scale *= 1.0e+1; e -= 1; }
        if( esign<0 ){
          result = s / scale;
          result /= 1.0e+308;
        }else{
          result = s * scale;
          result *= 1.0e+308;
        }
      }else if( e>=342 ){
        if( esign<0 ){
          result = 0.0*s;
        }else{
          result = 1e308*1e308*s;  /* Infinity */
        }
      }else{
        /* 1.0e+22 is the largest power of 10 than can be
        ** represented exactly. */
        while( e%22 ) { scale *= 1.0e+1; e -= 1; }
        while( e>0 ) { scale *= 1.0e+22; e -= 22; }
        if( esign<0 ){
          result = s / scale;
        }else{
          result = s * scale;
        }
      }
    } else {
      result = (double)s;
    }
  }

  /* store the result */
  *pResult = result;

  /* return true if number and no extra non-whitespace chracters after */
  return z>=zEnd && nDigits>0 && eValid && nonNum==0;
}

/*
** tointeger(X):  If X is any value (integer, double, blob, or string) that
** can be losslessly converted into an integer, then make the conversion and
** return the result.  Otherwise, return NULL.
*/
static void tointegerFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  assert( argc==1 );
  (void)argc;
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_FLOAT: {
      double rVal = sqlite3_value_double(argv[0]);
      sqlite3_int64 iVal = (sqlite3_int64)rVal;
      if( rVal==(double)iVal ){
        sqlite3_result_int64(context, iVal);
      }
      break;
    }
    case SQLITE_INTEGER: {
      sqlite3_result_int64(context, sqlite3_value_int64(argv[0]));
      break;
    }
    case SQLITE_BLOB: {
      const unsigned char *zBlob = sqlite3_value_blob(argv[0]);
      if( zBlob ){
        int nBlob = sqlite3_value_bytes(argv[0]);
        if( nBlob==sizeof(sqlite3_int64) ){
          sqlite3_int64 iVal;
          if( TOTYPE_BIGENDIAN ){
            int i;
            unsigned char zBlobRev[sizeof(sqlite3_int64)];
            for(i=0; i<sizeof(sqlite3_int64); i++){
              zBlobRev[i] = zBlob[sizeof(sqlite3_int64)-1-i];
            }
            memcpy(&iVal, zBlobRev, sizeof(sqlite3_int64));
          }else{
            memcpy(&iVal, zBlob, sizeof(sqlite3_int64));
          }
          sqlite3_result_int64(context, iVal);
        }
      }
      break;
    }
    case SQLITE_TEXT: {
      const unsigned char *zStr = sqlite3_value_text(argv[0]);
      if( zStr ){
        int nStr = sqlite3_value_bytes(argv[0]);
        if( nStr && !totypeIsspace(zStr[0]) ){
          sqlite3_int64 iVal;
          if( !totypeAtoi64((const char*)zStr, &iVal, nStr) ){
            sqlite3_result_int64(context, iVal);
          }
        }
      }
      break;
    }
    default: {
      assert( sqlite3_value_type(argv[0])==SQLITE_NULL );
      break;
    }
  }
}

/*
** toreal(X): If X is any value (integer, double, blob, or string) that can
** be losslessly converted into a real number, then do so and return that
** real number.  Otherwise return NULL.
*/
#if defined(_MSC_VER)
#pragma warning(disable: 4748)
#pragma optimize("", off)
#endif
static void torealFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  assert( argc==1 );
  (void)argc;
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_FLOAT: {
      sqlite3_result_double(context, sqlite3_value_double(argv[0]));
      break;
    }
    case SQLITE_INTEGER: {
      sqlite3_int64 iVal = sqlite3_value_int64(argv[0]);
      double rVal = (double)iVal;
      if( iVal==(sqlite3_int64)rVal ){
        sqlite3_result_double(context, rVal);
      }
      break;
    }
    case SQLITE_BLOB: {
      const unsigned char *zBlob = sqlite3_value_blob(argv[0]);
      if( zBlob ){
        int nBlob = sqlite3_value_bytes(argv[0]);
        if( nBlob==sizeof(double) ){
          double rVal;
          if( TOTYPE_LITTLEENDIAN ){
            int i;
            unsigned char zBlobRev[sizeof(double)];
            for(i=0; i<sizeof(double); i++){
              zBlobRev[i] = zBlob[sizeof(double)-1-i];
            }
            memcpy(&rVal, zBlobRev, sizeof(double));
          }else{
            memcpy(&rVal, zBlob, sizeof(double));
          }
          sqlite3_result_double(context, rVal);
        }
      }
      break;
    }
    case SQLITE_TEXT: {
      const unsigned char *zStr = sqlite3_value_text(argv[0]);
      if( zStr ){
        int nStr = sqlite3_value_bytes(argv[0]);
        if( nStr && !totypeIsspace(zStr[0]) && !totypeIsspace(zStr[nStr-1]) ){
          double rVal;
          if( totypeAtoF((const char*)zStr, &rVal, nStr) ){
            sqlite3_result_double(context, rVal);
            return;
          }
        }
      }
      break;
    }
    default: {
      assert( sqlite3_value_type(argv[0])==SQLITE_NULL );
      break;
    }
  }
}
#if defined(_MSC_VER)
#pragma optimize("", on)
#pragma warning(default: 4748)
#endif

#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_totype_init(
  sqlite3 *db,
  char **pzErrMsg,
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
  rc = sqlite3_create_function(db, "tointeger", 1, SQLITE_UTF8, 0,
                               tointegerFunc, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "toreal", 1, SQLITE_UTF8, 0,
                                 torealFunc, 0, 0);
  }
  return rc;
}
Changes to SQLite.Interop/src/win/SQLite.Interop.rc.
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
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











-
+
+
+
+
+








-
+


-
+








-
-
-
+
+
+

-
-
-
-
-
+
+
+
+
+













+









-
+


/*
 * SQLite.Interop.rc -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 */

#if !defined(_WIN32_WCE)
#include "winresrc.h"
#else
#include "windows.h"
#endif
#endif /* !defined(_WIN32_WCE) */

#if !defined(VS_FF_NONE)
#  define VS_FF_NONE            0x00000000L
#endif /* !defined(VS_FF_NONE) */

#include "..\core\sqlite3.h"
#include "interop.h"

/*
** English (U.S.) resources
*/

#ifdef _WIN32
#if defined(_WIN32)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#endif /* defined(_WIN32) */

/*
** Version
*/

VS_VERSION_INFO VERSIONINFO
 FILEVERSION INTEROP_RC_VERSION
 PRODUCTVERSION INTEROP_RC_VERSION
 FILEFLAGSMASK 0x17L
#ifdef _DEBUG
 FILEFLAGS 0x1L
 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#if defined(_DEBUG)
 FILEFLAGS VS_FF_DEBUG
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x4L
 FILETYPE 0x2L
 FILESUBTYPE 0x0L
 FILEFLAGS VS_FF_NONE
#endif /* defined(_DEBUG) */
 FILEOS VOS__WINDOWS32
 FILETYPE VFT_DLL
 FILESUBTYPE VFT2_UNKNOWN
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "CompanyName", "Robert Simpson, et al."
            VALUE "FileDescription", "System.Data.SQLite Interop Assembly"
            VALUE "FileVersion", INTEROP_VERSION
            VALUE "InternalName", "SQLite.Interop"
            VALUE "LegalCopyright", "Public Domain"
            VALUE "OriginalFilename", "SQLite.Interop.dll"
            VALUE "ProductName", "System.Data.SQLite"
            VALUE "ProductVersion", INTEROP_VERSION
            VALUE "SourceId", INTEROP_SOURCE_ID " " INTEROP_SOURCE_TIMESTAMP
            VALUE "SQLiteCompanyName", "D. Richard Hipp, et al."
            VALUE "SQLiteDescription", "SQLite Database Engine"
            VALUE "SQLiteCopyright", "http://www.sqlite.org/copyright.html"
            VALUE "SQLiteVersion", SQLITE_VERSION
            VALUE "SQLiteSourceId", SQLITE_SOURCE_ID
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
        VALUE "Translation", 0x409, 0x4b0
    END
END
Changes to SQLite.Interop/src/win/interop.c.
8
9
10
11
12
13
14








15
16
17
18
19
20
21
22
23
24


25
26
27
28
29
30
31
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







+
+
+
+
+
+
+
+










+
+







#define SQLITE_API __declspec(dllexport)

#include "../core/sqlite3.c"

#if defined(INTEROP_VIRTUAL_TABLE) && SQLITE_VERSION_NUMBER >= 3004001
#include "../ext/vtshim.c"
#endif

#if defined(INTEROP_TOTYPE_EXTENSION)
#include "../ext/totype.c"
#endif

#if defined(INTEROP_REGEXP_EXTENSION)
#include "../ext/regexp.c"
#endif

#if defined(INTEROP_EXTENSION_FUNCTIONS)
#include "../contrib/extension-functions.c"
extern int RegisterExtensionFunctions(sqlite3 *db);
#endif

#ifdef SQLITE_OS_WIN
#if defined(INTEROP_CODEC)
#include "crypt.c"
#endif

#include "interop.h"

#define INTEROP_DEBUG_NONE           (0x0000)
#define INTEROP_DEBUG_CLOSE          (0x0001)
#define INTEROP_DEBUG_FINALIZE       (0x0002)
#define INTEROP_DEBUG_BACKUP_FINISH  (0x0004)
#define INTEROP_DEBUG_OPEN           (0x0008)
#define INTEROP_DEBUG_OPEN16         (0x0010)
212
213
214
215
216
217
218










219
220
221
222
223
224
225
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245







+
+
+
+
+
+
+
+
+
+







    }
  }else{
    ret = SQLITE_OK;
  }
  return ret;
}
#endif

SQLITE_API const char *sqlite3_libversion_interop(void)
{
  return INTEROP_VERSION;
}

SQLITE_API const char *sqlite3_sourceid_interop(void)
{
  return INTEROP_SOURCE_ID " " INTEROP_SOURCE_TIMESTAMP;
}

SQLITE_API int WINAPI sqlite3_open_interop(const char *filename, int flags, sqlite3 **ppdb)
{
  int ret;

#if defined(INTEROP_DEBUG) && (INTEROP_DEBUG & INTEROP_DEBUG_OPEN)
  sqlite3InteropDebug("sqlite3_open_interop(): calling sqlite3_open_v2(\"%s\", %d, %p)...\n", filename, flags, ppdb);
Changes to SQLite.Interop/src/win/interop.h.
1
2
3
4
5
6
7
8
9









10
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18








-
+
+
+
+
+
+
+
+
+

/*
 * interop.h -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 */

#ifndef INTEROP_VERSION
#define INTEROP_VERSION       "1.0.89.0"
#define INTEROP_VERSION          "1.0.90.0"
#endif

#ifndef INTEROP_SOURCE_ID
#define INTEROP_SOURCE_ID        "0000000000000000000000000000000000000000"
#endif

#ifndef INTEROP_SOURCE_TIMESTAMP
#define INTEROP_SOURCE_TIMESTAMP "0000-00-00 00:00:00 UTC"
#endif
Changes to SQLite.MSIL.nuspec.
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












-
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.MSIL.nuspec -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<package>
  <metadata>
    <id>System.Data.SQLite.MSIL</id>
    <version>1.0.89.0</version>
    <version>1.0.90.0</version>
    <authors>SQLite Development Team</authors>
    <description>An ADO.NET provider for SQLite (managed-only).</description>
    <language>en-US</language>
    <projectUrl>http://system.data.sqlite.org/</projectUrl>
    <iconUrl>http://system.data.sqlite.org/images/sqlite32.png</iconUrl>
    <licenseUrl>http://www.sqlite.org/copyright.html</licenseUrl>
    <tags>sqlite database ado.net provider interop</tags>
Changes to SQLite.nuspec.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

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

14
15
16
17
18
19
20
21













-
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.nuspec -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<package>
  <metadata>
    <id>System.Data.SQLite</id>
    <title>System.Data.SQLite (x86/x64)</title>
    <version>1.0.89.0</version>
    <version>1.0.90.0</version>
    <authors>SQLite Development Team</authors>
    <description>The official SQLite database engine for both x86 and x64 along with the ADO.NET provider.</description>
    <language>en-US</language>
    <projectUrl>http://system.data.sqlite.org/</projectUrl>
    <iconUrl>http://system.data.sqlite.org/images/sqlite32.png</iconUrl>
    <licenseUrl>http://www.sqlite.org/copyright.html</licenseUrl>
    <tags>sqlite database ado.net provider interop</tags>
Changes to SQLite.x64.nuspec.
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












-
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.x64.nuspec -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<package>
  <metadata>
    <id>System.Data.SQLite.x64</id>
    <version>1.0.89.0</version>
    <version>1.0.90.0</version>
    <authors>SQLite Development Team</authors>
    <description>The official SQLite database engine combined with a complete ADO.NET provider all rolled into a single mixed-mode assembly for x64.</description>
    <language>en-US</language>
    <projectUrl>http://system.data.sqlite.org/</projectUrl>
    <iconUrl>http://system.data.sqlite.org/images/sqlite32.png</iconUrl>
    <licenseUrl>http://www.sqlite.org/copyright.html</licenseUrl>
    <tags>sqlite database ado.net provider interop</tags>
Changes to SQLite.x86.nuspec.
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












-
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.x86.nuspec -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<package>
  <metadata>
    <id>System.Data.SQLite.x86</id>
    <version>1.0.89.0</version>
    <version>1.0.90.0</version>
    <authors>SQLite Development Team</authors>
    <description>The official SQLite database engine combined with a complete ADO.NET provider all rolled into a single mixed-mode assembly for x86.</description>
    <language>en-US</language>
    <projectUrl>http://system.data.sqlite.org/</projectUrl>
    <iconUrl>http://system.data.sqlite.org/images/sqlite32.png</iconUrl>
    <licenseUrl>http://www.sqlite.org/copyright.html</licenseUrl>
    <tags>sqlite database ado.net provider interop</tags>
Changes to Setup/build.bat.
243
244
245
246
247
248
249















































250
251
252
253
254
255
256
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303







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








IF DEFINED LOGGING GOTO skip_setLogging
IF DEFINED NOLOG GOTO skip_setLogging

SET LOGGING="/logger:FileLogger,Microsoft.Build.Engine;Logfile=%LOGDIR%\%LOGPREFIX%_%CONFIGURATION%_%PLATFORM%_%YEAR%_%LOGSUFFIX%.log;Verbosity=diagnostic"

:skip_setLogging

IF NOT DEFINED NOPROPS (
  IF EXIST Externals\Eagle\bin\EagleShell.exe (
    IF DEFINED INTEROP_EXTRA_PROPS_FILE (
      REM
      REM HACK: This is used to work around a limitation of Visual Studio 2005
      REM       and 2008 that prevents the "InheritedPropertySheets" attribute
      REM       value from working correctly when it refers to a property that
      REM       evaluates to an empty string.
      REM
      %__ECHO% Externals\Eagle\bin\EagleShell.exe -evaluate "set fileName {SQLite.Interop/props/include.vsprops}; set data [readFile $fileName]; regsub -- {	InheritedPropertySheets=\"\"} $data {	InheritedPropertySheets=\"$^(INTEROP_EXTRA_PROPS_FILE^)\"} data; writeFile $fileName $data"

      IF ERRORLEVEL 1 (
        ECHO Property file modification of "SQLite.Interop\props\include.vsprops" failed.
        GOTO errors
      ) ELSE (
        ECHO Property file modification successful.
      )
    )
  ) ELSE (
    ECHO WARNING: Property file modification skipped, Eagle binaries are not available.
  )
) ELSE (
  ECHO WARNING: Property file modification skipped, disabled via NOPROPS environment variable.
)

IF NOT DEFINED NOTAG (
  IF EXIST Externals\Eagle\bin\EagleShell.exe (
    %__ECHO% Externals\Eagle\bin\EagleShell.exe -file Setup\sourceTag.eagle SourceIdMode SQLite.Interop\src\win\interop.h

    IF ERRORLEVEL 1 (
      ECHO Source tagging of "SQLite.Interop\src\win\interop.h" failed.
      GOTO errors
    )

    %__ECHO% Externals\Eagle\bin\EagleShell.exe -file Setup\sourceTag.eagle SourceIdMode System.Data.SQLite\SQLitePatchLevel.cs

    IF ERRORLEVEL 1 (
      ECHO Source tagging of "System.Data.SQLite\SQLitePatchLevel.cs" failed.
      GOTO errors
    )
  ) ELSE (
    ECHO WARNING: Source tagging skipped, Eagle binaries are not available.
  )
) ELSE (
  ECHO WARNING: Source tagging skipped, disabled via NOTAG environment variable.
)

%_VECHO% Logging = '%LOGGING%'
%_VECHO% MsBuildArgs = '%MSBUILD_ARGS%'

%__ECHO% MSBuild.exe "%SOLUTION%" "/target:%TARGET%" "/property:Configuration=%CONFIGURATION%" "/property:Platform=%PLATFORM%" %LOGGING% %MSBUILD_ARGS%

IF ERRORLEVEL 1 (
Added Setup/sourceTag.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# sourceTag.eagle -- Source Version Tag Tool
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle

proc usage { error } {
  if {[string length $error] > 0} then {puts stdout $error}

  puts stdout "usage:\
[file tail [info nameofexecutable]]\
[file tail [info script]] <SourceIdMode> <fileName>"

  #
  # NOTE: Indicate to the caller, if any, that we have failed.
  #
  exit 1
}

set modes [list \"SourceIdMode\"]
set argc [llength $argv]

if {$argc == 2} then {
  #
  # NOTE: Are we updating the "PatchLevel.cs" file?
  #
  set mode [lindex $argv 0]

  if {[string length $mode] > 0} then {
    #
    # NOTE: Get the file name to read/update/write.
    #
    set fileName [lindex $argv 1]

    #
    # NOTE: Make sure the file name provided is not obviously
    #       invalid.
    #
    if {[string length $fileName] > 0} then {
      #
      # NOTE: Read all the data out of the text file.
      #
      set data [readFile $fileName]

      #
      # NOTE: Normalize to Unix line-endings.
      #
      set data [string map [list \r\n \n] $data]; # Unix.

      #
      # NOTE: Figure out what mode we are in.
      #
      switch -exact -nocase -- $mode {
        SourceIdMode {
          #
          # NOTE: Query the source identifier from Fossil, if available.
          #       If we are not within an active checkout, this will fail.
          #
          set pattern {^checkout:\s+([^\s]+)\s+(.*)\s+$}

          if {[catch {set exec [exec -success Success -directory \
                  [file dirname $fileName] -- fossil info]}] || \
              [regexp -line -- $pattern $exec dummy id timeStamp] == 0} then {
            #
            # NOTE: We could not query the source identifier(s); therefore,
            #       use obviously invalid ones.  We would also be able to
            #       use null values here except that these values end up in
            #       native C header files as well (i.e. not just managed
            #       assembly attribute values).
            #
            set id 0000000000000000000000000000000000000000
            set timeStamp "0000-00-00 00:00:00 UTC"
          }

          #
          # NOTE: Match against this pattern in the "PatchLevel.cs"
          #       file (this pattern is fairly strict to prevent
          #       false-positives).
          #
          set pattern1 {AssemblySourceId\(.*?\)}
          set pattern2 {AssemblySourceTimeStamp\(.*?\)}
          set pattern3 {INTEROP_SOURCE_ID\s+".*?"}
          set pattern4 {INTEROP_SOURCE_TIMESTAMP\s+".*?"}

          #
          # NOTE: Build the final replacement specification string.
          #
          set subSpec1 [appendArgs AssemblySourceId(\" $id \" )]
          set subSpec2 [appendArgs AssemblySourceTimeStamp(\" $timeStamp \" )]
          set subSpec3 [appendArgs INTEROP_SOURCE_ID "        \"" $id \"]
          set subSpec4 [appendArgs INTEROP_SOURCE_TIMESTAMP " \"" $timeStamp \"]

          #
          # NOTE: Perform the replacements in the original data
          #       (first match only).
          #
          set count 0

          incr count [regsub -nocase -- $pattern1 $data $subSpec1 data]
          incr count [regsub -nocase -- $pattern2 $data $subSpec2 data]
          incr count [regsub -nocase -- $pattern3 $data $subSpec3 data]
          incr count [regsub -nocase -- $pattern4 $data $subSpec4 data]

          #
          # NOTE: If we actually replaced anything, we need to write back
          #       to the original file; otherwise, leave it alone.
          #
          if {$count > 0} then {
            #
            # NOTE: Show how we tagged it.
            #
            puts stdout [appendArgs "tagged \"" $fileName "\" " $mode \
                " " $id " " $timeStamp]

            #
            # NOTE: Re-write the original file with the modified data.
            #
            writeFile $fileName [string map [list \n \r\n] $data]; # DOS.
          } else {
            #
            # NOTE: We could not replace the string.  This is considered
            #       an overall failure.
            #
            usage [appendArgs "pattern \"" $pattern "\" not found in \"" \
                $fileName \"]
          }
        }
        default {
          usage [appendArgs "unknown mode, must be " [join $modes " "]]
        }
      }
    } else {
      usage "invalid file name"
    }
  } else {
    usage [appendArgs "invalid mode, must be " [join $modes " "]]
  }
} else {
  usage ""
}
Added Setup/test.bat.





































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@ECHO OFF

::
:: test.bat --
::
:: Eagle Shell Testing Tool
::
:: Written by Joe Mistachkin.
:: Released to the public domain, use at your own risk!
::

SETLOCAL

REM SET __ECHO=ECHO
REM SET __ECHO2=ECHO
REM SET __ECHO3=ECHO
IF NOT DEFINED _AECHO (SET _AECHO=REM)
IF NOT DEFINED _CECHO (SET _CECHO=REM)
IF NOT DEFINED _VECHO (SET _VECHO=REM)

%_AECHO% Running %0 %*

SET ROOT=%~dp0\..
SET ROOT=%ROOT:\\=\%

%_VECHO% Root = '%ROOT%'

SET TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

CALL :fn_ResetErrorLevel

%__ECHO2% PUSHD "%ROOT%"

IF ERRORLEVEL 1 (
  ECHO Could not change directory to "%ROOT%".
  GOTO errors
)

IF NOT DEFINED PREARGS (
  %_AECHO% No pre-arguments specified, using default...
  SET PREARGS=-interactive -noExit -initialize -runtimeOption autoSelect
)

%_VECHO% PreArgs = '%PREARGS%'

IF NOT DEFINED POSTARGS (
  %_AECHO% No post-arguments specified, using default...
  SET POSTARGS=-file Tests\empty.eagle
)

%_VECHO% PostArgs = '%POSTARGS%'

%_CECHO% Externals\Eagle\bin\EagleShell.exe %PREARGS% %* %POSTARGS%
%__ECHO% Externals\Eagle\bin\EagleShell.exe %PREARGS% %* %POSTARGS%

IF ERRORLEVEL 1 (
  ECHO Received non-zero return code from the Eagle Shell.
  GOTO errors
)

%__ECHO2% POPD

IF ERRORLEVEL 1 (
  ECHO Could not restore directory.
  GOTO errors
)

GOTO no_errors

:fn_ResetErrorLevel
  VERIFY > NUL
  GOTO :EOF

:fn_SetErrorLevel
  VERIFY MAYBE 2> NUL
  GOTO :EOF

:usage
  ECHO.
  ECHO Usage: %~nx0 [...]
  GOTO errors

:errors
  CALL :fn_SetErrorLevel
  ENDLOCAL
  ECHO.
  ECHO Failure, errors were encountered.
  GOTO end_of_file

:no_errors
  CALL :fn_ResetErrorLevel
  ENDLOCAL
  ECHO.
  ECHO Success, no errors were encountered.
  GOTO end_of_file

:end_of_file
%__ECHO% EXIT /B %ERRORLEVEL%
Changes to Setup/verify.lst.
125
126
127
128
129
130
131

132

133
134
135
136
137
138
139
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141







+

+







  Setup/set_x64_2008.bat
  Setup/set_x64_2010.bat
  Setup/set_x64_2012.bat
  Setup/set_x86_2005.bat
  Setup/set_x86_2008.bat
  Setup/set_x86_2010.bat
  Setup/set_x86_2012.bat
  Setup/sourceTag.eagle
  Setup/SQLite.iss
  Setup/test.bat
  Setup/test_all.bat
  Setup/test_ce.bat
  Setup/updateFileInfo.tcl
  Setup/verify.eagle
  Setup/verify.lst
  Setup/vsSp.bat
  SQLite.Beta.nuspec
233
234
235
236
237
238
239


240
241
242
243
244
245
246
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250







+
+







  SQLite.Interop/src/contrib/
  SQLite.Interop/src/contrib/extension-functions.c
  SQLite.Interop/src/core/
  SQLite.Interop/src/core/sqlite3.c
  SQLite.Interop/src/core/sqlite3.h
  SQLite.Interop/src/core/sqlite3ext.h
  SQLite.Interop/src/ext/
  SQLite.Interop/src/ext/regexp.c
  SQLite.Interop/src/ext/totype.c
  SQLite.Interop/src/ext/vtshim.c
  SQLite.Interop/src/win/
  SQLite.Interop/src/win/AssemblyInfo.cpp
  SQLite.Interop/src/win/crypt.c
  SQLite.Interop/src/win/interop.c
  SQLite.Interop/src/win/interop.h
  SQLite.Interop/src/win/SQLite.Interop.rc
257
258
259
260
261
262
263


264
265
266
267
268
269
270
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276







+
+







  SQLite.NET.Settings.targets.netFx35
  SQLite.NET.targets
  SQLite.nuspec
  SQLite.x64.nuspec
  SQLite.x86.nuspec
  System.Data.SQLite/
  System.Data.SQLite/AssemblyInfo.cs
  System.Data.SQLite/AssemblySourceIdAttribute.cs
  System.Data.SQLite/AssemblySourceTimeStampAttribute.cs
  System.Data.SQLite/DataTypes.xml
  System.Data.SQLite/LINQ/
  System.Data.SQLite/LINQ/SQLiteConnection_Linq.cs
  System.Data.SQLite/LINQ/SQLiteFactory_Linq.cs
  System.Data.SQLite/MetaDataCollections.xml
  System.Data.SQLite/SQLite3.cs
  System.Data.SQLite/SQLite3_UTF16.cs
291
292
293
294
295
296
297

298
299
300
301
302
303
304
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311







+







  System.Data.SQLite/SQLiteLog.cs
  System.Data.SQLite/SQLiteMetaDataCollectionNames.cs
  System.Data.SQLite/SQLiteModule.cs
  System.Data.SQLite/SQLiteModuleEnumerable.cs
  System.Data.SQLite/SQLiteModuleNoop.cs
  System.Data.SQLite/SQLiteParameter.cs
  System.Data.SQLite/SQLiteParameterCollection.cs
  System.Data.SQLite/SQLitePatchLevel.cs
  System.Data.SQLite/SQLiteStatement.cs
  System.Data.SQLite/SQLiteTransaction.cs
  System.Data.SQLite/SR.Designer.cs
  System.Data.SQLite/SR.resx
  System.Data.SQLite/System.Data.SQLite.2005.csproj
  System.Data.SQLite/System.Data.SQLite.2008.csproj
  System.Data.SQLite/System.Data.SQLite.2010.csproj
399
400
401
402
403
404
405

406
407
408
409
410
411
412
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420







+







  testlinq/Properties/
  testlinq/Properties/AssemblyInfo.cs
  testlinq/testlinq.2008.csproj
  testlinq/testlinq.2010.csproj
  testlinq/testlinq.2012.csproj
  Tests/
  Tests/all.eagle
  Tests/authorizer.eagle
  Tests/backup.eagle
  Tests/basic.eagle
  Tests/common.eagle
  Tests/empty.eagle
  Tests/installer.eagle
  Tests/Installer_Test_Vs2005.log
  Tests/Installer_Test_Vs2008.log
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
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







+



















+
+











+







  Tests/tkt-00f86f9739.eagle
  Tests/tkt-0d5b1ef362.eagle
  Tests/tkt-17045010df.eagle
  Tests/tkt-1c456ae75f.eagle
  Tests/tkt-201128cc88.eagle
  Tests/tkt-2c630bffa7.eagle
  Tests/tkt-2ce0870fad.eagle
  Tests/tkt-3113734605.eagle
  Tests/tkt-343d392b51.eagle
  Tests/tkt-3567020edf.eagle
  Tests/tkt-393d954be0.eagle
  Tests/tkt-3aa50d8413.eagle
  Tests/tkt-448d663d11.eagle
  Tests/tkt-47f4bac575.eagle
  Tests/tkt-48a6b8e4ca.eagle
  Tests/tkt-4a791e70ab.eagle
  Tests/tkt-544dba0a2f.eagle
  Tests/tkt-59edc1018b.eagle
  Tests/tkt-6434e23a0f.eagle
  Tests/tkt-6c6ecccc5f.eagle
  Tests/tkt-72905c9a77.eagle
  Tests/tkt-7e3fa93744.eagle
  Tests/tkt-84718e79fa.eagle
  Tests/tkt-8554170e09.eagle
  Tests/tkt-8b7d179c3c.eagle
  Tests/tkt-8c3bee31c8.eagle
  Tests/tkt-996d13cd87.eagle
  Tests/tkt-9ba9346f75.eagle
  Tests/tkt-aba4549801.eagle
  Tests/tkt-ac47dd230a.eagle
  Tests/tkt-ae5267b863.eagle
  Tests/tkt-b4a7ddc83f.eagle
  Tests/tkt-bb4b04d457.eagle
  Tests/tkt-c010fa6584.eagle
  Tests/tkt-ccfa69fc32.eagle
  Tests/tkt-e06c4caff3.eagle
  Tests/tkt-e1b2e0f769.eagle
  Tests/tkt-e30b820248.eagle
  Tests/tkt-e47b3d8346.eagle
  Tests/tkt-f2c47a01eb.eagle
  Tests/tkt-f8dbab8baf.eagle
  Tests/tkt-fe50b8c2e8.eagle
  Tests/Uninstaller_Test_Vs2005.log
  Tests/Uninstaller_Test_Vs2008.log
  Tests/Uninstaller_Test_Vs2010.log
  Tests/Uninstaller_Test_Vs2012.log
  Tests/version.eagle
  Tests/vtab.eagle
Changes to System.Data.SQLite.Linq/AssemblyInfo.cs.
44
45
46
47
48
49
50
51
52


44
45
46
47
48
49
50


51
52







-
-
+
+
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.89.0")]
[assembly: AssemblyFileVersion("1.0.89.0")]
[assembly: AssemblyVersion("1.0.90.0")]
[assembly: AssemblyFileVersion("1.0.90.0")]
Changes to System.Data.SQLite/AssemblyInfo.cs.
63
64
65
66
67
68
69
70

71
72

73
63
64
65
66
67
68
69

70
71

72
73







-
+

-
+

//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.89.0")]
[assembly: AssemblyVersion("1.0.90.0")]
#if !PLATFORM_COMPACTFRAMEWORK
[assembly: AssemblyFileVersion("1.0.89.0")]
[assembly: AssemblyFileVersion("1.0.90.0")]
#endif
Added System.Data.SQLite/AssemblySourceIdAttribute.cs.










































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Joe Mistachkin (joe@mistachkin.com)
 *
 * Released to the public domain, use at your own risk!
 ********************************************************/

using System;

namespace System.Data.SQLite
{
    /// <summary>
    /// Defines a source code identifier custom attribute for an assembly
    /// manifest.
    /// </summary>
    [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
    public sealed class AssemblySourceIdAttribute : Attribute
    {
        /// <summary>
        /// Constructs an instance of this attribute class using the specified
        /// source code identifier value.
        /// </summary>
        /// <param name="value">
        /// The source code identifier value to use.
        /// </param>
        public AssemblySourceIdAttribute(string value)
        {
            sourceId = value;
        }

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

        private string sourceId;
        /// <summary>
        /// Gets the source code identifier value.
        /// </summary>
        public string SourceId
        {
            get { return sourceId; }
        }
    }
}
Added System.Data.SQLite/AssemblySourceTimeStampAttribute.cs.










































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Joe Mistachkin (joe@mistachkin.com)
 *
 * Released to the public domain, use at your own risk!
 ********************************************************/

using System;

namespace System.Data.SQLite
{
    /// <summary>
    /// Defines a source code time-stamp custom attribute for an assembly
    /// manifest.
    /// </summary>
    [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
    public sealed class AssemblySourceTimeStampAttribute : Attribute
    {
        /// <summary>
        /// Constructs an instance of this attribute class using the specified
        /// source code time-stamp value.
        /// </summary>
        /// <param name="value">
        /// The source code time-stamp value to use.
        /// </param>
        public AssemblySourceTimeStampAttribute(string value)
        {
            sourceTimeStamp = value;
        }

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

        private string sourceTimeStamp;
        /// <summary>
        /// Gets the source code time-stamp value.
        /// </summary>
        public string SourceTimeStamp
        {
            get { return sourceTimeStamp; }
        }
    }
}
Changes to System.Data.SQLite/SQLite3.cs.
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67







-
+







    internal const string PublicKey =
        "002400000480000094000000060200000024000052534131000400000100010005a288de5687c4e1" +
        "b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0" +
        "a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421" +
        "d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c";

#if !PLATFORM_COMPACTFRAMEWORK
    internal const string DesignerVersion = "1.0.89.0";
    internal const string DesignerVersion = "1.0.90.0";
#endif

    /// <summary>
    /// The opaque pointer returned to us by the sqlite provider
    /// </summary>
    protected internal SQLiteConnectionHandle _sql;
    protected string _fileName;
360
361
362
363
364
365
366
























367
368
369
370
371
372
373
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







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







    internal static string SQLiteSourceId
    {
      get
      {
        return UTF8ToString(UnsafeNativeMethods.sqlite3_sourceid(), -1);
      }
    }

    internal static string InteropVersion
    {
        get
        {
#if !SQLITE_STANDARD
            return UTF8ToString(UnsafeNativeMethods.sqlite3_libversion_interop(), -1);
#else
            return null;
#endif
        }
    }

    internal static string InteropSourceId
    {
        get
        {
#if !SQLITE_STANDARD
            return UTF8ToString(UnsafeNativeMethods.sqlite3_sourceid_interop(), -1);
#else
            return null;
#endif
        }
    }

    internal override bool AutoCommit
    {
      get
      {
        return IsAutocommit(_sql, _sql);
      }
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
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







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

-
+

-
-
-
+
+
+

-
+

-
+




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

-
+

-
-
-
+
+
+

-
+

-
+







        return UnsafeNativeMethods.sqlite3_changes(_sql);
#endif
      }
    }

    internal override long MemoryUsed
    {
      get
      {
        get
        {
            return StaticMemoryUsed;
        }
    }

    internal static long StaticMemoryUsed
    {
        get
        {
#if !PLATFORM_COMPACTFRAMEWORK
        return UnsafeNativeMethods.sqlite3_memory_used();
            return UnsafeNativeMethods.sqlite3_memory_used();
#elif !SQLITE_STANDARD
        long bytes = 0;
        UnsafeNativeMethods.sqlite3_memory_used_interop(ref bytes);
        return bytes;
            long bytes = 0;
            UnsafeNativeMethods.sqlite3_memory_used_interop(ref bytes);
            return bytes;
#else
        throw new NotImplementedException();
            throw new NotImplementedException();
#endif
      }
        }
    }

    internal override long MemoryHighwater
    {
      get
      {
        get
        {
            return StaticMemoryHighwater;
        }
    }

    internal static long StaticMemoryHighwater
    {
        get
        {
#if !PLATFORM_COMPACTFRAMEWORK
        return UnsafeNativeMethods.sqlite3_memory_highwater(0);
            return UnsafeNativeMethods.sqlite3_memory_highwater(0);
#elif !SQLITE_STANDARD
        long bytes = 0;
        UnsafeNativeMethods.sqlite3_memory_highwater_interop(0, ref bytes);
        return bytes;
            long bytes = 0;
            UnsafeNativeMethods.sqlite3_memory_highwater_interop(0, ref bytes);
            return bytes;
#else
        throw new NotImplementedException();
            throw new NotImplementedException();
#endif
      }
        }
    }

    /// <summary>
    /// Returns non-zero if the underlying native connection handle is owned
    /// by this instance.
    /// </summary>
    internal override bool OwnHandle
458
459
460
461
462
463
464















































































465
466


467
468

469
470




































471


472
473
474
475
476
477
478
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







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

-
+


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







        SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_config_int(
            SQLiteConfigOpsEnum.SQLITE_CONFIG_MEMSTATUS, value ? 1 : 0);

        return rc;
    }

    /// <summary>
    /// Attempts to free as much heap memory as possible for the database connection.
    /// </summary>
    /// <returns>A standard SQLite return code (i.e. zero for success and non-zero for failure).</returns>
    internal override SQLiteErrorCode ReleaseMemory()
    {
        SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_db_release_memory(_sql);
        return rc;
    }

    /// <summary>
    /// Attempts to free N bytes of heap memory by deallocating non-essential memory
    /// allocations held by the database library. Memory used to cache database pages
    /// to improve performance is an example of non-essential memory.  This is a no-op
    /// returning zero if the SQLite core library was not compiled with the compile-time
    /// option SQLITE_ENABLE_MEMORY_MANAGEMENT.  Optionally, attempts to reset and/or
    /// compact the Win32 native heap, if applicable.
    /// </summary>
    /// <param name="nBytes">
    /// The requested number of bytes to free.
    /// </param>
    /// <param name="reset">
    /// Non-zero to attempt a heap reset.
    /// </param>
    /// <param name="compact">
    /// Non-zero to attempt heap compaction.
    /// </param>
    /// <param name="nFree">
    /// The number of bytes actually freed.  This value may be zero.
    /// </param>
    /// <param name="resetOk">
    /// This value will be non-zero if the heap reset was successful.
    /// </param>
    /// <param name="nLargest">
    /// The size of the largest committed free block in the heap, in bytes.
    /// This value will be zero unless heap compaction is enabled.
    /// </param>
    /// <returns>
    /// A standard SQLite return code (i.e. zero for success and non-zero
    /// for failure).
    /// </returns>
    internal static SQLiteErrorCode StaticReleaseMemory(
        int nBytes,
        bool reset,
        bool compact,
        ref int nFree,
        ref bool resetOk,
        ref uint nLargest
        )
    {
        SQLiteErrorCode rc = SQLiteErrorCode.Ok;

        int nFreeLocal = UnsafeNativeMethods.sqlite3_release_memory(nBytes);
        uint nLargestLocal = 0;
        bool resetOkLocal = false;

#if !DEBUG && WINDOWS // NOTE: Should be "WIN32HEAP && !MEMDEBUG && WINDOWS"
        if ((rc == SQLiteErrorCode.Ok) && reset)
        {
            rc = UnsafeNativeMethods.sqlite3_win32_reset_heap();

            if (rc == SQLiteErrorCode.Ok)
                resetOkLocal = true;
        }

        if ((rc == SQLiteErrorCode.Ok) && compact)
            rc = UnsafeNativeMethods.sqlite3_win32_compact_heap(ref nLargestLocal);
#else
        if (reset || compact)
            rc = SQLiteErrorCode.NotFound;
#endif

        nFree = nFreeLocal;
        nLargest = nLargestLocal;
        resetOk = resetOkLocal;

        return rc;
    }

    /// <summary>
    /// Shutdown the SQLite engine so that it can be restarted with different config options.
    /// We depend on auto initialization to recover.
    /// Shutdown the SQLite engine so that it can be restarted with different
    /// configuration options.  We depend on auto initialization to recover.
    /// </summary>
    /// <returns>Returns a result code</returns>
    /// <returns>Returns a standard SQLite result code.</returns>
    internal override SQLiteErrorCode Shutdown()
    {
        return StaticShutdown(false);
    }

    /// <summary>
    /// Shutdown the SQLite engine so that it can be restarted with different
    /// configuration options.  We depend on auto initialization to recover.
    /// </summary>
    /// <param name="directories">
    /// Non-zero to reset the database and temporary directories to their
    /// default values, which should be null for both.  This parameter has no
    /// effect on non-Windows operating systems.
    /// </param>
    /// <returns>Returns a standard SQLite result code.</returns>
    internal static SQLiteErrorCode StaticShutdown(
        bool directories
        )
    {
        SQLiteErrorCode rc = SQLiteErrorCode.Ok;

        if (directories)
        {
#if WINDOWS
            if (rc == SQLiteErrorCode.Ok)
                rc = UnsafeNativeMethods.sqlite3_win32_set_directory(1, null);

            if (rc == SQLiteErrorCode.Ok)
                rc = UnsafeNativeMethods.sqlite3_win32_set_directory(2, null);
#else
#if !NET_COMPACT_20 && TRACE_CONNECTION
            Trace.WriteLine(
                "Shutdown: Cannot reset directories on this platform.");
#endif
#endif
        }

        if (rc == SQLiteErrorCode.Ok)
        SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_shutdown();
            rc = UnsafeNativeMethods.sqlite3_shutdown();

        return rc;
    }

    /// <summary>
    /// Determines if the associated native connection handle is open.
    /// </summary>
    /// <returns>
672
673
674
675
676
677
678





679



680
681
682
683
684
685
686
828
829
830
831
832
833
834
835
836
837
838
839

840
841
842
843
844
845
846
847
848
849







+
+
+
+
+
-
+
+
+







        throw new SQLiteException(n, GetLastError());

      return n; // We reset OK, no schema changes
    }

    internal override string GetLastError()
    {
        return GetLastError(null);
    }

    internal override string GetLastError(string defValue)
    {
      return SQLiteBase.GetLastError(_sql, _sql);
        string result = SQLiteBase.GetLastError(_sql, _sql);
        if (String.IsNullOrEmpty(result)) result = defValue;
        return result;
    }

    internal override SQLiteStatement Prepare(SQLiteConnection cnn, string strSql, SQLiteStatement previous, uint timeoutMS, out string strRemain)
    {
      if (!String.IsNullOrEmpty(strSql))
      {
        //
2001
2002
2003
2004
2005
2006
2007






2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023





2024
2025
2026
2027
2028
2029
2030
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204







+
+
+
+
+
+
















+
+
+
+
+







    {
      return UnsafeNativeMethods.sqlite3_extended_errcode(_sql);
    }

    /// Add a log message via the SQLite sqlite3_log interface.
    internal override void LogMessage(SQLiteErrorCode iErrCode, string zMessage)
    {
      StaticLogMessage(iErrCode, zMessage);
    }

    /// Add a log message via the SQLite sqlite3_log interface.
    internal static void StaticLogMessage(SQLiteErrorCode iErrCode, string zMessage)
    {
      UnsafeNativeMethods.sqlite3_log(iErrCode, ToUTF8(zMessage));
    }

#if INTEROP_CODEC
    internal override void SetPassword(byte[] passwordBytes)
    {
      SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_key(_sql, passwordBytes, passwordBytes.Length);
      if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
    }

    internal override void ChangePassword(byte[] newPasswordBytes)
    {
      SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_rekey(_sql, newPasswordBytes, (newPasswordBytes == null) ? 0 : newPasswordBytes.Length);
      if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
    }
#endif

    internal override void SetAuthorizerHook(SQLiteAuthorizerCallback func)
    {
      UnsafeNativeMethods.sqlite3_set_authorizer(_sql, func, IntPtr.Zero);
    }

    internal override void SetUpdateHook(SQLiteUpdateCallback func)
    {
      UnsafeNativeMethods.sqlite3_update_hook(_sql, func, IntPtr.Zero);
    }

    internal override void SetCommitHook(SQLiteCommitCallback func)
Changes to System.Data.SQLite/SQLiteBase.cs.
66
67
68
69
70
71
72





73
74
75
76
77
78
79
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84







+
+
+
+
+







    /// Sets the status of the memory usage tracking subsystem in the SQLite core library.  By default, this is enabled.
    /// If this is disabled, memory usage tracking will not be performed.  This is not really a per-connection value, it is
    /// global to the process.
    /// </summary>
    /// <param name="value">Non-zero to enable memory usage tracking, zero otherwise.</param>
    /// <returns>A standard SQLite return code (i.e. zero for success and non-zero for failure).</returns>
    internal abstract SQLiteErrorCode SetMemoryStatus(bool value);
    /// <summary>
    /// Attempts to free as much heap memory as possible for the database connection.
    /// </summary>
    /// <returns>A standard SQLite return code (i.e. zero for success and non-zero for failure).</returns>
    internal abstract SQLiteErrorCode ReleaseMemory();
    /// <summary>
    /// Shutdown the SQLite engine so that it can be restarted with different config options.
    /// We depend on auto initialization to recover.
    /// </summary>
    internal abstract SQLiteErrorCode Shutdown();
    /// <summary>
    /// Determines if the associated native connection handle is open.
111
112
113
114
115
116
117












118
119
120
121
122
123
124
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141







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







    internal abstract void SetTimeout(int nTimeoutMS);
    /// <summary>
    /// Returns the text of the last error issued by SQLite
    /// </summary>
    /// <returns></returns>
    internal abstract string GetLastError();

    /// <summary>
    /// Returns the text of the last error issued by SQLite -OR- the specified default error text if
    /// none is available from the SQLite core library.
    /// </summary>
    /// <param name="defValue">
    /// The error text to return in the event that one is not available from the SQLite core library.
    /// </param>
    /// <returns>
    /// The error text.
    /// </returns>
    internal abstract string GetLastError(string defValue);

    /// <summary>
    /// When pooling is enabled, force this connection to be disposed rather than returned to the pool
    /// </summary>
    internal abstract void ClearPool();

    /// <summary>
    /// When pooling is enabled, returns the number of pool entries matching the current file name.
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
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







+




















+
+
+
+
+







    internal abstract void LogMessage(SQLiteErrorCode iErrCode, string zMessage);

#if INTEROP_CODEC
    internal abstract void SetPassword(byte[] passwordBytes);
    internal abstract void ChangePassword(byte[] newPasswordBytes);
#endif

    internal abstract void SetAuthorizerHook(SQLiteAuthorizerCallback func);
    internal abstract void SetUpdateHook(SQLiteUpdateCallback func);
    internal abstract void SetCommitHook(SQLiteCommitCallback func);
    internal abstract void SetTraceCallback(SQLiteTraceCallback func);
    internal abstract void SetRollbackHook(SQLiteRollbackCallback func);
    internal abstract SQLiteErrorCode SetLogCallback(SQLiteLogCallback func);

    /// <summary>
    /// Checks if the SQLite core library has been initialized in the current process.
    /// </summary>
    /// <returns>
    /// Non-zero if the SQLite core library has been initialized in the current process,
    /// zero otherwise.
    /// </returns>
    internal abstract bool IsInitialized();

    internal abstract int GetCursorForTable(SQLiteStatement stmt, int database, int rootPage);
    internal abstract long GetRowIdForCursor(SQLiteStatement stmt, int cursor);

    internal abstract object GetValue(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, SQLiteType typ);

    /// <summary>
    /// Returns non-zero if the given database connection is in autocommit mode.
    /// Autocommit mode is on by default.  Autocommit mode is disabled by a BEGIN
    /// statement.  Autocommit mode is re-enabled by a COMMIT or ROLLBACK.
    /// </summary>
    internal abstract bool AutoCommit
    {
      get;
    }

    internal abstract SQLiteErrorCode FileControl(string zDbName, int op, IntPtr pArg);

Changes to System.Data.SQLite/SQLiteCommand.cs.
20
21
22
23
24
25
26
27
28




29
30
31
32
33
34
35
20
21
22
23
24
25
26


27
28
29
30
31
32
33
34
35
36
37







-
-
+
+
+
+







#if !PLATFORM_COMPACTFRAMEWORK
  [Designer("SQLite.Designer.SQLiteCommandDesigner, SQLite.Designer, Version=" + SQLite3.DesignerVersion + ", Culture=neutral, PublicKeyToken=db937bc2d44ff139"), ToolboxItem(true)]
#endif
  public sealed class SQLiteCommand : DbCommand, ICloneable
  {
    /// <summary>
    /// The default connection string to be used when creating a temporary
    /// connection to execute a command via the static <see cref="Execute" />
    /// method.
    /// connection to execute a command via the static
    /// <see cref="Execute(string,SQLiteExecuteType,string,object[])" /> or
    /// <see cref="Execute(string,SQLiteExecuteType,CommandBehavior,string,object[])" />
    /// methods.
    /// </summary>
    private static readonly string DefaultConnectionString = "Data Source=:memory:;";

    /// <summary>
    /// The command text this command is based on
    /// </summary>
    private string _commandText;
688
689
690
691
692
693
694










































695
696
697
698
699
700
701
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
739
740
741
742
743
744
745







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







    /// </returns>
    public static object Execute(
        string commandText,
        SQLiteExecuteType executeType,
        string connectionString,
        params object[] args
        )
    {
        return Execute(
            commandText, executeType, CommandBehavior.Default,
            connectionString, args);
    }

    /// <summary>
    /// This method creates a new connection, executes the query using the given
    /// execution type and command behavior, closes the connection, and returns
    /// the results.  If the connection string is null, a temporary in-memory
    /// database connection will be used.
    /// </summary>
    /// <param name="commandText">
    /// The text of the command to be executed.
    /// </param>
    /// <param name="executeType">
    /// The execution type for the command.  This is used to determine which method
    /// of the command object to call, which then determines the type of results
    /// returned, if any.
    /// </param>
    /// <param name="commandBehavior">
    /// The command behavior flags for the command.
    /// </param>
    /// <param name="connectionString">
    /// The connection string to the database to be opened, used, and closed.  If
    /// this parameter is null, a temporary in-memory databse will be used.
    /// </param>
    /// <param name="args">
    /// The SQL parameter values to be used when building the command object to be
    /// executed, if any.
    /// </param>
    /// <returns>
    /// The results of the query -OR- null if no results were produced from the
    /// given execution type.
    /// </returns>
    public static object Execute(
        string commandText,
        SQLiteExecuteType executeType,
        CommandBehavior commandBehavior,
        string connectionString,
        params object[] args
        )
    {
        if (connectionString == null)
            connectionString = DefaultConnectionString;

        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
        {
            connection.Open();
722
723
724
725
726
727
728
729

730
731
732
733

734
735
736
737

738
739
740
741
742
743
744
745
746
747
748
749

750
751
752
753
754
755
756
766
767
768
769
770
771
772

773
774
775
776

777
778
779
780

781
782
783
784
785
786
787
788
789
790
791
792

793
794
795
796
797
798
799
800







-
+



-
+



-
+











-
+







                            //
                            // NOTE: Do nothing.
                            //
                            break;
                        }
                    case SQLiteExecuteType.NonQuery:
                        {
                            return command.ExecuteNonQuery();
                            return command.ExecuteNonQuery(commandBehavior);
                        }
                    case SQLiteExecuteType.Scalar:
                        {
                            return command.ExecuteScalar();
                            return command.ExecuteScalar(commandBehavior);
                        }
                    case SQLiteExecuteType.Reader:
                        {
                            return command.ExecuteReader();
                            return command.ExecuteReader(commandBehavior);
                        }
                }
            }
        }

        return null;
    }

    /// <summary>
    /// Overrides the default behavior to return a SQLiteDataReader specialization class
    /// </summary>
    /// <param name="behavior">The flags to be associated with the reader</param>
    /// <param name="behavior">The flags to be associated with the reader.</param>
    /// <returns>A SQLiteDataReader</returns>
    public new SQLiteDataReader ExecuteReader(CommandBehavior behavior)
    {
      CheckDisposed();
      SQLiteConnection.Check(_cnn);
      InitializeForReader();

778
779
780
781
782
783
784
785

786














787
788
789
790
791


792
793
794
795
796
797
798
799
800
801
802

803
804
805
806

807
808

















809
810
811
812
813
814
815
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848

849
850
851
852
853
854
855
856
857
858
859
860

861
862
863
864
865
866


867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890







-
+

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




-
+
+










-
+




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







    {
      _activeReader = null;
    }

    /// <summary>
    /// Execute the command and return the number of rows inserted/updated affected by it.
    /// </summary>
    /// <returns></returns>
    /// <returns>The number of rows inserted/updated affected by it.</returns>
    public override int ExecuteNonQuery()
    {
        CheckDisposed();
        SQLiteConnection.Check(_cnn);
        return ExecuteNonQuery(CommandBehavior.Default);
    }

    /// <summary>
    /// Execute the command and return the number of rows inserted/updated affected by it.
    /// </summary>
    /// <param name="behavior">The flags to be associated with the reader.</param>
    /// <returns>The number of rows inserted/updated affected by it.</returns>
    public int ExecuteNonQuery(
        CommandBehavior behavior
        )
    {
      CheckDisposed();
      SQLiteConnection.Check(_cnn);

      using (SQLiteDataReader reader = ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.SingleResult))
      using (SQLiteDataReader reader = ExecuteReader(behavior |
          CommandBehavior.SingleRow | CommandBehavior.SingleResult))
      {
        while (reader.NextResult()) ;
        return reader.RecordsAffected;
      }
    }

    /// <summary>
    /// Execute the command and return the first column of the first row of the resultset
    /// (if present), or null if no resultset was returned.
    /// </summary>
    /// <returns>The first column of the first row of the first resultset from the query</returns>
    /// <returns>The first column of the first row of the first resultset from the query.</returns>
    public override object ExecuteScalar()
    {
      CheckDisposed();
      SQLiteConnection.Check(_cnn);
      return ExecuteScalar(CommandBehavior.Default);

      using (SQLiteDataReader reader = ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.SingleResult))
    }

    /// <summary>
    /// Execute the command and return the first column of the first row of the resultset
    /// (if present), or null if no resultset was returned.
    /// </summary>
    /// <param name="behavior">The flags to be associated with the reader.</param>
    /// <returns>The first column of the first row of the first resultset from the query.</returns>
    public object ExecuteScalar(
        CommandBehavior behavior
        )
    {
      CheckDisposed();
      SQLiteConnection.Check(_cnn);

      using (SQLiteDataReader reader = ExecuteReader(behavior |
          CommandBehavior.SingleRow | CommandBehavior.SingleResult))
      {
        if (reader.Read())
          return reader[0];
      }
      return null;
    }

Changes to System.Data.SQLite/SQLiteConnection.cs.
10
11
12
13
14
15
16

17
18
19
20
21
22
23
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24







+







  using System;
  using System.Data;
  using System.Data.Common;
  using System.Diagnostics;
  using System.Collections.Generic;
  using System.Globalization;
  using System.ComponentModel;
  using System.Reflection;
  using System.Runtime.InteropServices;
  using System.IO;
  using System.Text;

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

  /// <summary>
49
50
51
52
53
54
55

56



57
58
59
60
61
62
63
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68







+

+
+
+







      /// The data reader associated with this event, if any.
      /// </summary>
      public readonly IDataReader DataReader;

      /// <summary>
      /// The critical handle associated with this event, if any.
      /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
      public readonly CriticalHandle CriticalHandle;
#else
      public readonly object CriticalHandle;
#endif

      /// <summary>
      /// Command or message text associated with this event, if any.
      /// </summary>
      public readonly string Text;

      /// <summary>
79
80
81
82
83
84
85

86



87
88
89
90
91
92
93
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102







+

+
+
+







      /// <param name="data">The extra data, if any.</param>
      internal ConnectionEventArgs(
          SQLiteConnectionEventType eventType,
          StateChangeEventArgs eventArgs,
          IDbTransaction transaction,
          IDbCommand command,
          IDataReader dataReader,
#if !PLATFORM_COMPACTFRAMEWORK
          CriticalHandle criticalHandle,
#else
          object criticalHandle,
#endif
          string text,
          object data
          )
      {
          EventType = eventType;
          EventArgs = eventArgs;
          Transaction = transaction;
364
365
366
367
368
369
370





371
372
373
374
375

376
377
378
379
380
381
382
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396







+
+
+
+
+




-
+







    private const string _masterdb = "sqlite_master";
    private const string _tempmasterdb = "sqlite_temp_master";
    #endregion

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

    #region Private Static Data
    /// <summary>
    /// The managed assembly containing this type.
    /// </summary>
    private static readonly Assembly _assembly = typeof(SQLiteConnection).Assembly;

    /// <summary>
    /// Object used to synchronize access to the static instance data
    /// for this class.
    /// </summary>
    private static object _syncRoot = new object();
    private static readonly object _syncRoot = new object();

    /// <summary>
    /// Static variable to store the connection event handlers to call.
    /// </summary>
    private static event SQLiteConnectionEventHandler _handlers;

#if SQLITE_STANDARD && !PLATFORM_COMPACTFRAMEWORK
460
461
462
463
464
465
466

467
468
469
470
471

472
473
474
475
476
477
478
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494







+





+







    /// </summary>
    private bool _parseViaFramework;

    internal bool _binaryGuid;

    internal long _version;

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

    private SQLiteAuthorizerCallback _authorizerCallback;
    private SQLiteUpdateCallback _updateCallback;
    private SQLiteCommitCallback _commitCallback;
    private SQLiteTraceCallback _traceCallback;
    private SQLiteRollbackCallback _rollbackCallback;
    #endregion

    ///////////////////////////////////////////////////////////////////////////////////////////////
2206
2207
2208
2209
2210
2211
2212



2213
2214
2215
2216
2217
2218
2219
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238







+
+
+







                  {
                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA foreign_keys={0}", boolValue ? "ON" : "OFF");
                      cmd.ExecuteNonQuery();
                  }
              }
          }

          if (_authorizerHandler != null)
              _sql.SetAuthorizerHook(_authorizerCallback);

          if (_commitHandler != null)
            _sql.SetCommitHook(_commitCallback);

          if (_updateHandler != null)
            _sql.SetUpdateHook(_updateCallback);

          if (_rollbackHandler != null)
2381
2382
2383
2384
2385
2386
2387





















2388
2389
2390
2391
2392
2393
2394
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434







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








        if (_sql == null)
          throw new InvalidOperationException("Database connection not valid for getting number of changes.");

        return _sql.Changes;
      }
    }

    /// <summary>
    /// Returns non-zero if the given database connection is in autocommit mode.
    /// Autocommit mode is on by default.  Autocommit mode is disabled by a BEGIN
    /// statement.  Autocommit mode is re-enabled by a COMMIT or ROLLBACK.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
    public bool AutoCommit
    {
        get
        {
            CheckDisposed();

            if (_sql == null)
                throw new InvalidOperationException("Database connection not valid for getting autocommit mode.");

            return _sql.AutoCommit;
        }
    }

    /// <summary>
    /// Returns the amount of memory (in bytes) currently in use by the SQLite core library.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
2419
2420
2421
2422
2423
2424
2425





















































































2426
2427
2428
2429
2430
2431
2432
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557







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








        if (_sql == null)
          throw new InvalidOperationException("Database connection not valid for getting maximum memory used.");

          return _sql.MemoryHighwater;
      }
    }

    /// <summary>
    /// Returns various global memory statistics for the SQLite core library via
    /// a dictionary of key/value pairs.  Currently, only the "MemoryUsed" and
    /// "MemoryHighwater" keys are returned and they have values that correspond
    /// to the values that could be obtained via the <see cref="MemoryUsed" />
    /// and <see cref="MemoryHighwater" /> connection properties.
    /// </summary>
    /// <param name="statistics">
    /// This dictionary will be populated with the global memory statistics.  It
    /// will be created if necessary.
    /// </param>
    public static void GetMemoryStatistics(
        ref IDictionary<string, long> statistics
        )
    {
        if (statistics == null)
            statistics = new Dictionary<string, long>();

        statistics["MemoryUsed"] = SQLite3.StaticMemoryUsed;
        statistics["MemoryHighwater"] = SQLite3.StaticMemoryHighwater;
    }

    /// <summary>
    /// Attempts to free as much heap memory as possible for this database connection.
    /// </summary>
    public void ReleaseMemory()
    {
        CheckDisposed();

        if (_sql == null)
            throw new InvalidOperationException("Database connection not valid for releasing memory.");

        SQLiteErrorCode rc = _sql.ReleaseMemory();

        if (rc != SQLiteErrorCode.Ok)
        {
            throw new SQLiteException(rc,
                _sql.GetLastError("Could not release connection memory."));
        }
    }

    /// <summary>
    /// Attempts to free N bytes of heap memory by deallocating non-essential memory
    /// allocations held by the database library. Memory used to cache database pages
    /// to improve performance is an example of non-essential memory.  This is a no-op
    /// returning zero if the SQLite core library was not compiled with the compile-time
    /// option SQLITE_ENABLE_MEMORY_MANAGEMENT.  Optionally, attempts to reset and/or
    /// compact the Win32 native heap, if applicable.
    /// </summary>
    /// <param name="nBytes">
    /// The requested number of bytes to free.
    /// </param>
    /// <param name="reset">
    /// Non-zero to attempt a heap reset.
    /// </param>
    /// <param name="compact">
    /// Non-zero to attempt heap compaction.
    /// </param>
    /// <param name="nFree">
    /// The number of bytes actually freed.  This value may be zero.
    /// </param>
    /// <param name="resetOk">
    /// This value will be non-zero if the heap reset was successful.
    /// </param>
    /// <param name="nLargest">
    /// The size of the largest committed free block in the heap, in bytes.
    /// This value will be zero unless heap compaction is enabled.
    /// </param>
    /// <returns>
    /// A standard SQLite return code (i.e. zero for success and non-zero
    /// for failure).
    /// </returns>
    public static SQLiteErrorCode ReleaseMemory(
        int nBytes,
        bool reset,
        bool compact,
        ref int nFree,
        ref bool resetOk,
        ref uint nLargest
        )
    {
        return SQLite3.StaticReleaseMemory(
            nBytes, reset, compact, ref nFree, ref resetOk, ref nLargest);
    }

    /// <summary>
    /// Sets the status of the memory usage tracking subsystem in the SQLite core library.  By default, this is enabled.
    /// If this is disabled, memory usage tracking will not be performed.  This is not really a per-connection value, it is
    /// global to the process.
    /// </summary>
    /// <param name="value">Non-zero to enable memory usage tracking, zero otherwise.</param>
2443
2444
2445
2446
2447
2448
2449
2450

2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465


























































































2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481

2482







2483
2484
2485
2486
2487
2488

2489
2490
2491
2492
2493
2494
2495
2496








































2497
2498
2499
2500
2501
2502
2503
2568
2569
2570
2571
2572
2573
2574

2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697

2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708

2709
2710








2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757







-
+















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
















+
-
+
+
+
+
+
+
+




-

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







    /// </summary>
    public static string DefineConstants
    {
        get { return SQLite3.DefineConstants; }
    }

    /// <summary>
    /// Returns the version of the underlying SQLite database engine
    /// Returns the version of the underlying SQLite core library.
    /// </summary>
    public static string SQLiteVersion
    {
      get { return SQLite3.SQLiteVersion; }
    }

    /// <summary>
    /// This method returns the string whose value is the same as the
    /// SQLITE_SOURCE_ID C preprocessor macro used when compiling the
    /// SQLite core library.
    /// </summary>
    public static string SQLiteSourceId
    {
      get { return SQLite3.SQLiteSourceId; }
    }

    /// <summary>
    /// This method returns the version of the interop SQLite assembly
    /// used.  If the SQLite interop assembly is not in use or the
    /// necessary information cannot be obtained for any reason, a null
    /// value may be returned.
    /// </summary>
    public static string InteropVersion
    {
      get { return SQLite3.InteropVersion; }
    }

    /// <summary>
    /// This method returns the string whose value contains the unique
    /// identifier for the source checkout used to build the interop
    /// assembly.  If the SQLite interop assembly is not in use or the
    /// necessary information cannot be obtained for any reason, a null
    /// value may be returned.
    /// </summary>
    public static string InteropSourceId
    {
      get { return SQLite3.InteropSourceId; }
    }

    /// <summary>
    /// This method returns the version of the managed components used
    /// to interact with the SQLite core library.  If the necessary
    /// information cannot be obtained for any reason, a null value may
    /// be returned.
    /// </summary>
    public static string ProviderVersion
    {
        get
        {
            return (_assembly != null) ?
                _assembly.GetName().Version.ToString() : null;
        }
    }

    /// <summary>
    /// This method returns the string whose value contains the unique
    /// identifier for the source checkout used to build the managed
    /// components currently executing.  If the necessary information
    /// cannot be obtained for any reason, a null value may be returned.
    /// </summary>
    public static string ProviderSourceId
    {
        get
        {
            if (_assembly == null)
                return null;

            string sourceId = null;

            if (_assembly.IsDefined(typeof(AssemblySourceIdAttribute), false))
            {
                AssemblySourceIdAttribute attribute =
                    (AssemblySourceIdAttribute)_assembly.GetCustomAttributes(
                        typeof(AssemblySourceIdAttribute), false)[0];

                sourceId = attribute.SourceId;
            }

            string sourceTimeStamp = null;

            if (_assembly.IsDefined(typeof(AssemblySourceTimeStampAttribute), false))
            {
                AssemblySourceTimeStampAttribute attribute =
                    (AssemblySourceTimeStampAttribute)_assembly.GetCustomAttributes(
                        typeof(AssemblySourceTimeStampAttribute), false)[0];

                sourceTimeStamp = attribute.SourceTimeStamp;
            }

            if ((sourceId != null) || (sourceTimeStamp != null))
            {
                if (sourceId == null)
                    sourceId = "0000000000000000000000000000000000000000";

                if (sourceTimeStamp == null)
                    sourceTimeStamp = "0000-00-00 00:00:00 UTC";

                return String.Format("{0} {1}", sourceId, sourceTimeStamp);
            }
            else
            {
                return null;
            }
        }
    }

    /// <summary>
    /// Returns the state of the connection.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
    public override ConnectionState State
    {
      get
      {
        CheckDisposed();
        return _connectionState;
      }
    }

    /// <summary>
    /// Passes a shutdown request off to SQLite.
    /// Passes a shutdown request to the SQLite core library.  Does not throw
    /// an exception if the shutdown request fails.
    /// </summary>
    /// <returns>
    /// A standard SQLite return code (i.e. zero for success and non-zero for
    /// failure).
    /// </returns>
    public SQLiteErrorCode Shutdown()
    {
        CheckDisposed();

        // make sure we have an instance of the base class
        if (_sql == null)
            throw new InvalidOperationException("Database connection not valid for shutdown.");
        {
            SortedList<string, string> opts = ParseConnectionString(
                _connectionString, _parseViaFramework);

            SetupSQLiteBase(opts);
        }
        if (_sql != null) return _sql.Shutdown();
        throw new InvalidOperationException("Database connection not active.");

        _sql.Close(true); /* NOTE: MUST be closed before shutdown. */
        SQLiteErrorCode rc = _sql.Shutdown();

#if !NET_COMPACT_20 && TRACE_CONNECTION
        if (rc != SQLiteErrorCode.Ok)
            System.Diagnostics.Trace.WriteLine(String.Format("Shutdown (Instance) Failed: {0}", rc));
#endif

        return rc;
    }

    /// <summary>
    /// Passes a shutdown request to the SQLite core library.  Throws an
    /// exception if the shutdown request fails and the no-throw parameter
    /// is non-zero.
    /// </summary>
    /// <param name="directories">
    /// Non-zero to reset the database and temporary directories to their
    /// default values, which should be null for both.
    /// </param>
    /// <param name="noThrow">
    /// When non-zero, throw an exception if the shutdown request fails.
    /// </param>
    public static void Shutdown(
        bool directories,
        bool noThrow
        )
    {
        SQLiteErrorCode rc = SQLite3.StaticShutdown(directories);

        if (rc != SQLiteErrorCode.Ok)
        {
#if !NET_COMPACT_20 && TRACE_CONNECTION
            System.Diagnostics.Trace.WriteLine(String.Format("Shutdown (Static) Failed: {0}", rc));
#endif

            if (!noThrow)
                throw new SQLiteException(rc, null);
        }
    }

    /// Enables or disabled extended result codes returned by SQLite
    public void SetExtendedResultCodes(bool bOnOff)
    {
      CheckDisposed();

2841
2842
2843
2844
2845
2846
2847
2848

2849
2850
2851
2852
2853
2854
2855
3095
3096
3097
3098
3099
3100
3101

3102
3103
3104
3105
3106
3107
3108
3109







-
+







          return Schema_ReservedWords();
      }
      throw new NotSupportedException();
    }

    private static DataTable Schema_ReservedWords()
    {
      DataTable tbl = new DataTable("MetaDataCollections");
      DataTable tbl = new DataTable("ReservedWords");

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("ReservedWord", typeof(string));
      tbl.Columns.Add("MaximumVersion", typeof(string));
      tbl.Columns.Add("MinimumVersion", typeof(string));

      tbl.BeginLoadData();
3829
3830
3831
3832
3833
3834
3835


































3836
3837
3838
3839
3840
3841
3842
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130







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







      }

      tbl.EndLoadData();
      tbl.AcceptChanges();

      return tbl;
    }

    /// <summary>
    /// This event is raised whenever SQLite encounters an action covered by the
    /// authorizer during query preparation.  Changing the value of the
    /// <see cref="AuthorizerEventArgs.ReturnCode" /> property will determine if
    /// the specific action will be allowed, ignored, or denied.  For the entire
    /// duration of the event, the associated connection and statement objects
    /// must not be modified, either directly or indirectly, by the called code.
    /// </summary>
    public event SQLiteAuthorizerEventHandler Authorize
    {
        add
        {
            CheckDisposed();

            if (_authorizerHandler == null)
            {
                _authorizerCallback = new SQLiteAuthorizerCallback(AuthorizerCallback);
                if (_sql != null) _sql.SetAuthorizerHook(_authorizerCallback);
            }
            _authorizerHandler += value;
        }
        remove
        {
            CheckDisposed();

            _authorizerHandler -= value;
            if (_authorizerHandler == null)
            {
                if (_sql != null) _sql.SetAuthorizerHook(null);
                _authorizerCallback = null;
            }
        }
    }

    /// <summary>
    /// This event is raised whenever SQLite makes an update/delete/insert into the database on
    /// this connection.  It only applies to the given connection.
    /// </summary>
    public event SQLiteUpdateEventHandler Update
    {
3859
3860
3861
3862
3863
3864
3865



















3866
3867
3868
3869
3870
3871
3872
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179







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







        if (_updateHandler == null)
        {
          if (_sql != null) _sql.SetUpdateHook(null);
          _updateCallback = null;
        }
      }
    }

    private SQLiteAuthorizerReturnCode AuthorizerCallback(
        IntPtr pUserData,
        SQLiteAuthorizerActionCode actionCode,
        IntPtr pArgument1,
        IntPtr pArgument2,
        IntPtr pDatabase,
        IntPtr pAuthContext)
    {
        AuthorizerEventArgs eventArgs = new AuthorizerEventArgs(pUserData, actionCode,
            SQLiteBase.UTF8ToString(pArgument1, -1), SQLiteBase.UTF8ToString(pArgument2, -1),
            SQLiteBase.UTF8ToString(pDatabase, -1), SQLiteBase.UTF8ToString(pAuthContext, -1),
            SQLiteAuthorizerReturnCode.Ok);

        if (_authorizerHandler != null)
            _authorizerHandler(this, eventArgs);

        return eventArgs.ReturnCode;
    }

    private void UpdateCallback(IntPtr puser, int type, IntPtr database, IntPtr table, Int64 rowid)
    {
      _updateHandler(this, new UpdateEventArgs(
        SQLiteBase.UTF8ToString(database, -1),
        SQLiteBase.UTF8ToString(table, -1),
        (UpdateEventType)type,
4000
4001
4002
4003
4004
4005
4006












4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024









4025
4026
4027
4028
4029
4030
4031
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359







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


















+
+
+
+
+
+
+
+
+







    /// Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing
    /// </summary>
    Off = 2,
  }

#if !PLATFORM_COMPACTFRAMEWORK
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
#endif
  internal delegate SQLiteAuthorizerReturnCode SQLiteAuthorizerCallback(
    IntPtr pUserData,
    SQLiteAuthorizerActionCode actionCode,
    IntPtr pArgument1,
    IntPtr pArgument2,
    IntPtr pDatabase,
    IntPtr pAuthContext
    );

#if !PLATFORM_COMPACTFRAMEWORK
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
#endif
  internal delegate void SQLiteUpdateCallback(IntPtr puser, int type, IntPtr database, IntPtr table, Int64 rowid);

#if !PLATFORM_COMPACTFRAMEWORK
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
#endif
  internal delegate int SQLiteCommitCallback(IntPtr puser);

#if !PLATFORM_COMPACTFRAMEWORK
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
#endif
  internal delegate void SQLiteTraceCallback(IntPtr puser, IntPtr statement);

#if !PLATFORM_COMPACTFRAMEWORK
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
#endif
  internal delegate void SQLiteRollbackCallback(IntPtr puser);

  /// <summary>
  /// Raised when authorization is required to perform an action contained
  /// within a SQL query.
  /// </summary>
  /// <param name="sender">The connection performing the action.</param>
  /// <param name="e">A <see cref="AuthorizerEventArgs" /> that contains the
  /// event data.</param>
  public delegate void SQLiteAuthorizerEventHandler(object sender, AuthorizerEventArgs e);

  /// <summary>
  /// Raised when a transaction is about to be committed.  To roll back a transaction, set the
  /// rollbackTrans boolean value to true.
  /// </summary>
  /// <param name="sender">The connection committing the transaction</param>
  /// <param name="e">Event arguments on the transaction</param>
  public delegate void SQLiteCommitHandler(object sender, CommitEventArgs e);
4086
4087
4088
4089
4090
4091
4092





















































































































4093
4094
4095
4096
4097
4098
4099
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
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544







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







    string destinationName,
    int pages,
    int remainingPages,
    int totalPages,
    bool retry
  );
  #endregion

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

  /// <summary>
  /// The data associated with a call into the authorizer.
  /// </summary>
  public class AuthorizerEventArgs : EventArgs
  {
      /// <summary>
      /// The user-defined native data associated with this event.  Currently,
      /// this will always contain the value of <see cref="IntPtr.Zero" />.
      /// </summary>
      public readonly IntPtr UserData;

      /// <summary>
      /// The action code responsible for the current call into the authorizer.
      /// </summary>
      public readonly SQLiteAuthorizerActionCode ActionCode;

      /// <summary>
      /// The first string argument for the current call into the authorizer.
      /// The exact value will vary based on the action code, see the
      /// <see cref="SQLiteAuthorizerActionCode" /> enumeration for possible
      /// values.
      /// </summary>
      public readonly string Argument1;

      /// <summary>
      /// The second string argument for the current call into the authorizer.
      /// The exact value will vary based on the action code, see the
      /// <see cref="SQLiteAuthorizerActionCode" /> enumeration for possible
      /// values.
      /// </summary>
      public readonly string Argument2;

      /// <summary>
      /// The database name for the current call into the authorizer, if
      /// applicable.
      /// </summary>
      public readonly string Database;

      /// <summary>
      /// The name of the inner-most trigger or view that is responsible for
      /// the access attempt or a null value if this access attempt is directly
      /// from top-level SQL code.
      /// </summary>
      public readonly string Context;

      /// <summary>
      /// The return code for the current call into the authorizer.
      /// </summary>
      public SQLiteAuthorizerReturnCode ReturnCode;

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

      /// <summary>
      /// Constructs an instance of this class with default property values.
      /// </summary>
      private AuthorizerEventArgs()
      {
          this.UserData = IntPtr.Zero;
          this.ActionCode = SQLiteAuthorizerActionCode.None;
          this.Argument1 = null;
          this.Argument2 = null;
          this.Database = null;
          this.Context = null;
          this.ReturnCode = SQLiteAuthorizerReturnCode.Ok;
      }

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

      /// <summary>
      /// Constructs an instance of this class with specific property values.
      /// </summary>
      /// <param name="pUserData">
      /// The user-defined native data associated with this event.
      /// </param>
      /// <param name="actionCode">
      /// The authorizer action code.
      /// </param>
      /// <param name="argument1">
      /// The first authorizer argument.
      /// </param>
      /// <param name="argument2">
      /// The second authorizer argument.
      /// </param>
      /// <param name="database">
      /// The database name, if applicable.
      /// </param>
      /// <param name="context">
      /// The name of the inner-most trigger or view that is responsible for
      /// the access attempt or a null value if this access attempt is directly
      /// from top-level SQL code.
      /// </param>
      /// <param name="returnCode">
      /// The authorizer return code.
      /// </param>
      internal AuthorizerEventArgs(
          IntPtr pUserData,
          SQLiteAuthorizerActionCode actionCode,
          string argument1,
          string argument2,
          string database,
          string context,
          SQLiteAuthorizerReturnCode returnCode
          )
          : this()
      {
          this.UserData = pUserData;
          this.ActionCode = actionCode;
          this.Argument1 = argument1;
          this.Argument2 = argument2;
          this.Database = database;
          this.Context = context;
          this.ReturnCode = returnCode;
      }
  }

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

  /// <summary>
  /// Whenever an update event is triggered on a connection, this enum will indicate
  /// exactly what type of operation is being performed.
  /// </summary>
Changes to System.Data.SQLite/SQLiteConvert.cs.
1470
1471
1472
1473
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
1470
1471
1472
1473
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
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748







-
-
+
+
+





-
-
+
+
+





-
+
+
+









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







      /// <summary>
      /// Do nothing.  No method will be called.
      /// </summary>
      None = 0,

      /// <summary>
      /// The command is not expected to return a result -OR- the result is not
      /// needed.  The <see cref="SQLiteCommand.ExecuteNonQuery" /> method will
      /// be called.
      /// needed.  The <see cref="SQLiteCommand.ExecuteNonQuery()" /> or
      /// <see cref="SQLiteCommand.ExecuteNonQuery(CommandBehavior)" />  method
      /// will be called.
      /// </summary>
      NonQuery = 1,

      /// <summary>
      /// The command is expected to return a scalar result -OR- the result should
      /// be limited to a scalar result.  The <see cref="SQLiteCommand.ExecuteScalar" />
      /// method will be called.
      /// be limited to a scalar result.  The <see cref="SQLiteCommand.ExecuteScalar()" />
      /// or <see cref="SQLiteCommand.ExecuteScalar(CommandBehavior)" /> method will
      /// be called.
      /// </summary>
      Scalar = 2,

      /// <summary>
      /// The command is expected to return <see cref="SQLiteDataReader" /> result.
      /// The <see cref="SQLiteCommand.ExecuteReader()" /> method will be called.
      /// The <see cref="SQLiteCommand.ExecuteReader()" /> or
      /// <see cref="SQLiteCommand.ExecuteReader(CommandBehavior)" /> method will
      /// be called.
      /// </summary>
      Reader = 3,

      /// <summary>
      /// Use the default command execution type.  Using this value is the same
      /// as using the <see cref="SQLiteExecuteType.NonQuery" /> value.
      /// </summary>
      Default = NonQuery /* TODO: Good default? */
  }

  /// <summary>
  /// The action code responsible for the current call into the authorizer.
  /// </summary>
  public enum SQLiteAuthorizerActionCode
  {
      /// <summary>
      /// No action is being performed.  This value should not be used from
      /// external code.
      /// </summary>
      None = -1,

      /// <summary>
      /// No longer used.
      /// </summary>
      Copy = 0,

      /// <summary>
      /// An index will be created.  The action-specific arguments are the
      /// index name and the table name.
      /// 
      /// </summary>
      CreateIndex = 1,

      /// <summary>
      /// A table will be created.  The action-specific arguments are the
      /// table name and a null value.
      /// </summary>
      CreateTable = 2,

      /// <summary>
      /// A temporary index will be created.  The action-specific arguments
      /// are the index name and the table name.
      /// </summary>
      CreateTempIndex = 3,

      /// <summary>
      /// A temporary table will be created.  The action-specific arguments
      /// are the table name and a null value.
      /// </summary>
      CreateTempTable = 4,

      /// <summary>
      /// A temporary trigger will be created.  The action-specific arguments
      /// are the trigger name and the table name.
      /// </summary>
      CreateTempTrigger = 5,

      /// <summary>
      /// A temporary view will be created.  The action-specific arguments are
      /// the view name and a null value.
      /// </summary>
      CreateTempView = 6,

      /// <summary>
      /// A trigger will be created.  The action-specific arguments are the
      /// trigger name and the table name.
      /// </summary>
      CreateTrigger = 7,

      /// <summary>
      /// A view will be created.  The action-specific arguments are the view
      /// name and a null value.
      /// </summary>
      CreateView = 8,

      /// <summary>
      /// A DELETE statement will be executed.  The action-specific arguments
      /// are the table name and a null value.
      /// </summary>
      Delete = 9,

      /// <summary>
      /// An index will be dropped.  The action-specific arguments are the
      /// index name and the table name.
      /// </summary>
      DropIndex = 10,

      /// <summary>
      /// A table will be dropped.  The action-specific arguments are the tables
      /// name and a null value.
      /// </summary>
      DropTable = 11,

      /// <summary>
      /// A temporary index will be dropped.  The action-specific arguments are
      /// the index name and the table name.
      /// </summary>
      DropTempIndex = 12,

      /// <summary>
      /// A temporary table will be dropped.  The action-specific arguments are
      /// the table name and a null value.
      /// </summary>
      DropTempTable = 13,

      /// <summary>
      /// A temporary trigger will be dropped.  The action-specific arguments
      /// are the trigger name and the table name.
      /// </summary>
      DropTempTrigger = 14,

      /// <summary>
      /// A temporary view will be dropped.  The action-specific arguments are
      /// the view name and a null value.
      /// </summary>
      DropTempView = 15,

      /// <summary>
      /// A trigger will be dropped.  The action-specific arguments are the
      /// trigger name and the table name.
      /// </summary>
      DropTrigger = 16,

      /// <summary>
      /// A view will be dropped.  The action-specific arguments are the view
      /// name and a null value.
      /// </summary>
      DropView = 17,

      /// <summary>
      /// An INSERT statement will be executed.  The action-specific arguments
      /// are the table name and a null value.
      /// </summary>
      Insert = 18,

      /// <summary>
      /// A PRAGMA statement will be executed.  The action-specific arguments
      /// are the name of the PRAGMA and the new value or a null value.
      /// </summary>
      Pragma = 19,

      /// <summary>
      /// A table column will be read.  The action-specific arguments are the
      /// table name and the column name.
      /// </summary>
      Read = 20,

      /// <summary>
      /// A SELECT statement will be executed.  The action-specific arguments
      /// are both null values.
      /// </summary>
      Select = 21,

      /// <summary>
      /// A transaction will be started, committed, or rolled back.  The
      /// action-specific arguments are the name of the operation (BEGIN,
      /// COMMIT, or ROLLBACK) and a null value.
      /// </summary>
      Transaction = 22,

      /// <summary>
      /// An UPDATE statement will be executed.  The action-specific arguments
      /// are the table name and the column name.
      /// </summary>
      Update = 23,

      /// <summary>
      /// A database will be attached to the connection.  The action-specific
      /// arguments are the database file name and a null value.
      /// </summary>
      Attach = 24,

      /// <summary>
      /// A database will be detached from the connection.  The action-specific
      /// arguments are the database name and a null value.
      /// </summary>
      Detach = 25,

      /// <summary>
      /// The schema of a table will be altered.  The action-specific arguments
      /// are the database name and the table name.
      /// </summary>
      AlterTable = 26,

      /// <summary>
      /// An index will be deleted and then recreated.  The action-specific
      /// arguments are the index name and a null value.
      /// </summary>
      Reindex = 27,

      /// <summary>
      /// A table will be analyzed to gathers statistics about it.  The
      /// action-specific arguments are the table name and a null value.
      /// </summary>
      Analyze = 28,

      /// <summary>
      /// A virtual table will be created.  The action-specific arguments are
      /// the table name and the module name.
      /// </summary>
      CreateVtable = 29,

      /// <summary>
      /// A virtual table will be dropped.  The action-specific arguments are
      /// the table name and the module name.
      /// </summary>
      DropVtable = 30,

      /// <summary>
      /// A SQL function will be called.  The action-specific arguments are a
      /// null value and the function name.
      /// </summary>
      Function = 31,

      /// <summary>
      /// A savepoint will be created, released, or rolled back.  The
      /// action-specific arguments are the name of the operation (BEGIN,
      /// RELEASE, or ROLLBACK) and the savepoint name.
      /// </summary>
      Savepoint = 32
  }

  /// <summary>
  /// The return code for the current call into the authorizer.
  /// </summary>
  public enum SQLiteAuthorizerReturnCode
  {
      /// <summary>
      /// The action will be allowed.
      /// </summary>
      Ok = 0,

      /// <summary>
      /// The overall action will be disallowed and an error message will be
      /// returned from the query preparation method.
      /// </summary>
      Deny = 1,

      /// <summary>
      /// The specific action will be disallowed; however, the overall action
      /// will continue.  The exact effects of this return code vary depending
      /// on the specific action, please refer to the SQLite core library
      /// documentation for futher details.
      /// </summary>
      Ignore = 2
  }

  /// <summary>
  /// Class used internally to determine the datatype of a column in a resultset
  /// </summary>
  internal sealed class SQLiteType
  {
    /// <summary>
Changes to System.Data.SQLite/SQLiteDataReader.cs.
1236
1237
1238
1239
1240
1241
1242

1243
1244
1245
1246
1247
1248
1249

1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261

1262
1263
1264
1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249

1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261

1262
1263
1264
1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278
1279







+






-
+











-
+









-
+







    {
      CheckDisposed();
      CheckClosed();
      if (_throwOnDisposed) SQLiteCommand.Check(_command);

      SQLiteStatement stmt = null;
      int fieldCount;
      bool schemaOnly = ((_commandBehavior & CommandBehavior.SchemaOnly) != 0);

      while (true)
      {
        if (stmt == null && _activeStatement != null && _activeStatement._sql != null && _activeStatement._sql.IsOpen())
        {
          // Reset the previously-executed statement
          _activeStatement._sql.Reset(_activeStatement);
          if (!schemaOnly) _activeStatement._sql.Reset(_activeStatement);

          // If we're only supposed to return a single rowset, step through all remaining statements once until
          // they are all done and return false to indicate no more resultsets exist.
          if ((_commandBehavior & CommandBehavior.SingleResult) != 0)
          {
            for (; ; )
            {
              stmt = _command.GetStatement(_activeStatementIndex + 1);
              if (stmt == null) break;
              _activeStatementIndex++;

              stmt._sql.Step(stmt);
              if (!schemaOnly) stmt._sql.Step(stmt);
              if (stmt._sql.ColumnCount(stmt) == 0)
              {
                if (_rowsAffected == -1) _rowsAffected = 0;
                int changes = 0;
                if (stmt.TryGetChanges(ref changes))
                    _rowsAffected += changes;
                else
                    return false;
              }
              stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!
              if (!schemaOnly) stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!
            }
            return false;
          }
        }

        // Get the next statement to execute
        stmt = _command.GetStatement(_activeStatementIndex + 1);
1286
1287
1288
1289
1290
1291
1292
1293

1294
1295

1296
1297
1298
1299
1300
1301
1302
1303
1304

1305
1306
1307


1308
1309
1310
1311
1312
1313
1314
1287
1288
1289
1290
1291
1292
1293

1294
1295

1296
1297
1298
1299
1300
1301
1302
1303
1304

1305
1306


1307
1308
1309
1310
1311
1312
1313
1314
1315







-
+

-
+








-
+

-
-
+
+







          _readingState = 1;

        _activeStatementIndex++;

        fieldCount = stmt._sql.ColumnCount(stmt);

        // If the statement is not a select statement or we're not retrieving schema only, then perform the initial step
        if ((_commandBehavior & CommandBehavior.SchemaOnly) == 0 || fieldCount == 0)
        if (!schemaOnly || (fieldCount == 0))
        {
          if (stmt._sql.Step(stmt))
          if (!schemaOnly && stmt._sql.Step(stmt))
          {
            _readingState = -1;
          }
          else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement
          {
            if (_rowsAffected == -1) _rowsAffected = 0;
            int changes = 0;
            if (stmt.TryGetChanges(ref changes))
                _rowsAffected += changes;
              _rowsAffected += changes;
            else
                return false;
            stmt._sql.Reset(stmt);
              return false;
            if (!schemaOnly) stmt._sql.Reset(stmt);
            continue; // Skip this command and move to the next, it was not a row-returning resultset
          }
          else // No rows, fieldCount is non-zero so stop here
          {
            _readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false
          }
        }
1359
1360
1361
1362
1363
1364
1365



1366
1367
1368
1369
1370
1371
1372
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376







+
+
+







    /// </summary>
    /// <returns>True if a new row was successfully loaded and is ready for processing</returns>
    public override bool Read()
    {
      CheckDisposed();
      CheckClosed();
      if (_throwOnDisposed) SQLiteCommand.Check(_command);

      if ((_commandBehavior & CommandBehavior.SchemaOnly) != 0)
        return false;

      if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true.
      {
        _readingState = 0;
        return true;
      }
      else if (_readingState == 0) // Actively reading rows
Changes to System.Data.SQLite/SQLiteException.cs.
324
325
326
327
328
329
330
331





332
333
324
325
326
327
328
329
330

331
332
333
334
335
336
337







-
+
+
+
+
+


    /// <summary>
    /// sqlite3_step() has another row ready
    /// </summary>
    Row = 100,
    /// <summary>
    /// sqlite3_step() has finished executing
    /// </summary>
    Done /* 101 */
    Done, /* 101 */
    /// <summary>
    /// Used to mask off extended result codes
    /// </summary>
    NonExtendedMask = 0xFF
  }
}
Changes to System.Data.SQLite/SQLiteLog.cs.
516
517
518
519
520
521
522
523

524
525
526
527
528
529

























530
531
532

533
534
535
536
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







-
+

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


-
+




                message = message.Trim();

                if (message.Length == 0)
                    message = "<empty>";
            }

            object errorCode = e.ErrorCode;
            bool success = false;
            string type = "error";

            if (errorCode is SQLiteErrorCode)
                success = ((SQLiteErrorCode)errorCode == SQLiteErrorCode.Ok);
            else if (errorCode is int)
                success = ((int)errorCode == 0);

            if ((errorCode is SQLiteErrorCode) || (errorCode is int))
            {
                SQLiteErrorCode rc = (SQLiteErrorCode)(int)errorCode;

                rc &= SQLiteErrorCode.NonExtendedMask;

                if (rc == SQLiteErrorCode.Ok)
                {
                    type = "message";
                }
                else if (rc == SQLiteErrorCode.Notice)
                {
                    type = "notice";
                }
                else if (rc == SQLiteErrorCode.Warning)
                {
                    type = "warning";
                }
                else if ((rc == SQLiteErrorCode.Row) ||
                    (rc == SQLiteErrorCode.Done))
                {
                    type = "data";
                }
            }

            Trace.WriteLine(String.Format(
                CultureInfo.CurrentCulture, "SQLite {0} ({1}): {2}",
                success ? "message" : "error", errorCode, message));
                type, errorCode, message));
#endif
        }
    }
}
Changes to System.Data.SQLite/SQLiteModule.cs.
961
962
963
964
965
966
967


















968
969
970
971
972
973
974
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992







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







        {
            constraintUsages = new SQLiteIndexConstraintUsage[nConstraint];
        }
        #endregion

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

        /// <summary>
        /// Determines if the native estimatedRows field can be used, based on
        /// the available version of the SQLite core library.
        /// </summary>
        /// <returns>
        /// Non-zero if the <see cref="EstimatedRows" /> property is supported
        /// by the SQLite core library.
        /// </returns>
        public bool CanUseEstimatedRows()
        {
            if (UnsafeNativeMethods.sqlite3_libversion_number() >= 3008002)
                return true;

            return false;
        }

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

        #region Public Properties
        private SQLiteIndexConstraintUsage[] constraintUsages;
        /// <summary>
        /// An array of <see cref="SQLiteIndexConstraintUsage" /> object
        /// instances, each containing information to be supplied to the SQLite
        /// core library.
        /// </summary>
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
1069
1070
1071
1072
1073
1074
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088










1089
1090
1091
1092
1093
1094
1095







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













-
-
-
-
-
-
-
-
-
-







        /// indicates that a default estimated cost value should be used.
        /// </summary>
        public double? EstimatedCost
        {
            get { return estimatedCost; }
            set { estimatedCost = value; }
        }

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

        private long? estimatedRows;
        /// <summary>
        /// Estimated number of rows returned.  Using a null value here
        /// indicates that a default estimated rows value should be used.
        /// </summary>
        public long? EstimatedRows
        {
            get { return estimatedRows; }
            set { estimatedRows = value; }
        }
        #endregion
    }
    #endregion

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

    #region SQLiteIndex Helper Class
    /// <summary>
    /// This class represents the various inputs and outputs used with the
    /// <see cref="ISQLiteManagedModule.BestIndex" /> method.
    /// </summary>
    public sealed class SQLiteIndex
    {
        #region Private Constants
        /// <summary>
        /// The default estimated cost for use with the
        /// <see cref="ISQLiteManagedModule.BestIndex" /> method.
        /// </summary>
        internal static readonly double DefaultEstimatedCost = double.MaxValue;
        #endregion

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

        #region Internal Constructors
        /// <summary>
        /// Constructs an instance of this class.
        /// </summary>
        /// <param name="nConstraint">
        /// The number of <see cref="SQLiteIndexConstraint" /> (and
        /// <see cref="SQLiteIndexConstraintUsage" />) instances to
1265
1266
1267
1268
1269
1270
1271


1272
1273










1274
1275
1276
1277
1278
1279
1280
1286
1287
1288
1289
1290
1291
1292
1293
1294


1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311







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








            SQLiteMarshal.WriteInt32(pIndex, offset,
                index.Outputs.OrderByConsumed);

            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
                sizeof(double));

            if (index.Outputs.EstimatedCost.HasValue)
            {
            SQLiteMarshal.WriteDouble(pIndex, offset,
                index.Outputs.EstimatedCost.GetValueOrDefault());
                SQLiteMarshal.WriteDouble(pIndex, offset,
                    index.Outputs.EstimatedCost.GetValueOrDefault());
            }

            if (index.Outputs.CanUseEstimatedRows() &&
                index.Outputs.EstimatedRows.HasValue)
            {
                SQLiteMarshal.WriteInt64(pIndex, offset,
                    index.Outputs.EstimatedRows.GetValueOrDefault());
            }
        }
        #endregion

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

        #region Public Properties
        private SQLiteIndexInputs inputs;
4411
4412
4413
4414
4415
4416
4417






























4418
4419
4420
4421
4422
4423
4424
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
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485







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







#else
            Marshal.WriteInt32(IntPtrForOffset(pointer, offset), value);
#endif
        }

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

        /// <summary>
        /// Writes an <see cref="Int64" /> value to the specified memory
        /// location.
        /// </summary>
        /// <param name="pointer">
        /// The <see cref="IntPtr" /> object instance representing the base
        /// memory location.
        /// </param>
        /// <param name="offset">
        /// The integer offset from the base memory location where the
        /// <see cref="Int64" /> value to be written is located.
        /// </param>
        /// <param name="value">
        /// The <see cref="Int64" /> value to write.
        /// </param>
        public static void WriteInt64(
            IntPtr pointer,
            int offset,
            long value
            )
        {
#if !PLATFORM_COMPACTFRAMEWORK
            Marshal.WriteInt64(pointer, offset, value);
#else
            Marshal.WriteInt64(IntPtrForOffset(pointer, offset), value);
#endif
        }

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

        /// <summary>
        /// Writes a <see cref="Double" /> value to the specified memory
        /// location.
        /// </summary>
        /// <param name="pointer">
        /// The <see cref="IntPtr" /> object instance representing the base
        /// memory location.
6837
6838
6839
6840
6841
6842
6843
6844


6845
6846
6847
6848
6849
6850
6851

6852
6853
6854
6855
6856
6857
6858
6898
6899
6900
6901
6902
6903
6904

6905
6906
6907
6908
6909
6910
6911
6912

6913
6914
6915
6916
6917
6918
6919
6920







-
+
+






-
+







        /// Modifies the specified <see cref="SQLiteIndex" /> object instance
        /// to contain the specified estimated cost.
        /// </summary>
        /// <param name="index">
        /// The <see cref="SQLiteIndex" /> object instance to modify.
        /// </param>
        /// <param name="estimatedCost">
        /// The estimated cost value to use.
        /// The estimated cost value to use.  Using a null value means that the
        /// default value provided by the SQLite core library should be used.
        /// </param>
        /// <returns>
        /// Non-zero upon success.
        /// </returns>
        protected virtual bool SetEstimatedCost(
            SQLiteIndex index,
            double estimatedCost
            double? estimatedCost
            )
        {
            if ((index == null) || (index.Outputs == null))
                return false;

            index.Outputs.EstimatedCost = estimatedCost;
            return true;
6870
6871
6872
6873
6874
6875
6876
6877
















































6878
6879
6880
6881
6882
6883
6884
6932
6933
6934
6935
6936
6937
6938

6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993







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







        /// <returns>
        /// Non-zero upon success.
        /// </returns>
        protected virtual bool SetEstimatedCost(
            SQLiteIndex index
            )
        {
            return SetEstimatedCost(index, SQLiteIndex.DefaultEstimatedCost);
            return SetEstimatedCost(index, null);
        }

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

        /// <summary>
        /// Modifies the specified <see cref="SQLiteIndex" /> object instance
        /// to contain the specified estimated rows.
        /// </summary>
        /// <param name="index">
        /// The <see cref="SQLiteIndex" /> object instance to modify.
        /// </param>
        /// <param name="estimatedRows">
        /// The estimated rows value to use.  Using a null value means that the
        /// default value provided by the SQLite core library should be used.
        /// </param>
        /// <returns>
        /// Non-zero upon success.
        /// </returns>
        protected virtual bool SetEstimatedRows(
            SQLiteIndex index,
            long? estimatedRows
            )
        {
            if ((index == null) || (index.Outputs == null))
                return false;

            index.Outputs.EstimatedRows = estimatedRows;
            return true;
        }

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

        /// <summary>
        /// Modifies the specified <see cref="SQLiteIndex" /> object instance
        /// to contain the default estimated rows.
        /// </summary>
        /// <param name="index">
        /// The <see cref="SQLiteIndex" /> object instance to modify.
        /// </param>
        /// <returns>
        /// Non-zero upon success.
        /// </returns>
        protected virtual bool SetEstimatedRows(
            SQLiteIndex index
            )
        {
            return SetEstimatedRows(index, null);
        }
        #endregion
        #endregion

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

        #region Public Properties
Added System.Data.SQLite/SQLitePatchLevel.cs.
















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Joe Mistachkin (joe@mistachkin.com)
 *
 * Released to the public domain, use at your own risk!
 ********************************************************/

using System.Data.SQLite;

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

[assembly: AssemblySourceId(null)]

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

[assembly: AssemblySourceTimeStamp(null)]
Changes to System.Data.SQLite/System.Data.SQLite.Files.targets.
11
12
13
14
15
16
17


18
19
20
21
22
23
24
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26







+
+







  ******************************************************************************
  **                            Core Files (Common)                           **
  ******************************************************************************
  -->

  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="AssemblySourceIdAttribute.cs" />
    <Compile Include="AssemblySourceTimeStampAttribute.cs" />
    <Compile Include="SQLite3.cs" />
    <Compile Include="SQLite3_UTF16.cs" />
    <Compile Include="SQLiteBackup.cs" />
    <Compile Include="SQLiteBase.cs" />
    <Compile Include="SQLiteCommand.cs">
      <SubType>Component</SubType>
    </Compile>
41
42
43
44
45
46
47

48
49
50
51
52
53
54
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57







+







    <Compile Include="SQLiteFunction.cs" />
    <Compile Include="SQLiteFunctionAttribute.cs" />
    <Compile Include="SQLiteKeyReader.cs" />
    <Compile Include="SQLiteLog.cs" />
    <Compile Include="SQLiteMetaDataCollectionNames.cs" />
    <Compile Include="SQLiteParameter.cs" />
    <Compile Include="SQLiteParameterCollection.cs" />
    <Compile Include="SQLitePatchLevel.cs" />
    <Compile Include="SQLiteStatement.cs" />
    <Compile Include="SQLiteTransaction.cs" />
    <Compile Include="SR.Designer.cs">
      <DependentUpon>SR.resx</DependentUpon>
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
    </Compile>
Changes to System.Data.SQLite/UnsafeNativeMethods.cs.
669
670
671
672
673
674
675
676

677
678
679
680
681
682
683
669
670
671
672
673
674
675

676
677
678
679
680
681
682
683







-
+







    //
    // NOTE: On the .NET Compact Framework, the native interop assembly must
    //       be used because it provides several workarounds to .NET Compact
    //       Framework limitations important for proper operation of the core
    //       System.Data.SQLite functionality (e.g. being able to bind
    //       parameters and handle column values of types Int64 and Double).
    //
    internal const string SQLITE_DLL = "SQLite.Interop.089.dll";
    internal const string SQLITE_DLL = "SQLite.Interop.090.dll";
#elif SQLITE_STANDARD
    //
    // NOTE: Otherwise, if the standard SQLite library is enabled, use it.
    //
    internal const string SQLITE_DLL = "sqlite3";
#elif USE_INTEROP_DLL
      //
767
768
769
770
771
772
773






774
775
776
777
778
779
780
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786







+
+
+
+
+
+








    // These functions add existing functionality on top of SQLite and require a little effort to
    // get working when using the standard SQLite library.
    #region interop added functionality

#if !SQLITE_STANDARD

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_libversion_interop();

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_sourceid_interop();

    [DllImport(SQLITE_DLL)]
    internal static extern SQLiteErrorCode sqlite3_close_interop(IntPtr db);

    [DllImport(SQLITE_DLL)]
    internal static extern SQLiteErrorCode sqlite3_create_function_interop(IntPtr db, byte[] strName, int nArgs, int nType, IntPtr pvUser, SQLiteCallback func, SQLiteCallback fstep, SQLiteFinalCallback ffinal, int needCollSeq);

    [DllImport(SQLITE_DLL)]
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050




1051































1052
1053
1054
1055
1056
1057
1058
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100







+





+
+
+
+

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







#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern SQLiteErrorCode sqlite3_overload_function(IntPtr db, IntPtr zName, int nArgs);

#if WINDOWS
#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
#else
    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
#endif
    //
    // NOTE: The "sqlite3_win32_set_directory" SQLite core library function is
    //       only supported on Windows.
    //
    internal static extern SQLiteErrorCode sqlite3_win32_set_directory(uint type, string value);

#if !DEBUG // NOTE: Should be "WIN32HEAP && !MEMDEBUG"
#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    //
    // NOTE: The "sqlite3_win32_reset_heap" SQLite core library function is
    //       only supported on Windows when the Win32 native allocator is in
    //       use (i.e. by default, in "Release" builds of System.Data.SQLite
    //       only).  By default, in "Debug" builds of System.Data.SQLite, the
    //       MEMDEBUG allocator is used.
    //
    internal static extern SQLiteErrorCode sqlite3_win32_reset_heap();

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    //
    // NOTE: The "sqlite3_win32_compact_heap" SQLite core library function is
    //       only supported on Windows when the Win32 native allocator is in
    //       use (i.e. by default, in "Release" builds of System.Data.SQLite
    //       only).  By default, in "Debug" builds of System.Data.SQLite, the
    //       MEMDEBUG allocator is used.
    //
    internal static extern SQLiteErrorCode sqlite3_win32_compact_heap(ref uint largest);
#endif
#endif

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_libversion();
1462
1463
1464
1465
1466
1467
1468







1469
1470
1471
1472
1473
1474
1475
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524







+
+
+
+
+
+
+







#endif
    internal static extern SQLiteErrorCode sqlite3_rekey(IntPtr db, byte[] key, int keylen);
#endif

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_set_authorizer(IntPtr db, SQLiteAuthorizerCallback func, IntPtr pvUser);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_update_hook(IntPtr db, SQLiteUpdateCallback func, IntPtr pvUser);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
1520
1521
1522
1523
1524
1525
1526







1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544







1545
1546
1547
1548
1549
1550
1551
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614







+
+
+
+
+
+
+


















+
+
+
+
+
+
+







    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_db_handle(IntPtr stmt);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern SQLiteErrorCode sqlite3_db_release_memory(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_db_filename(IntPtr db, IntPtr dbName);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_next_stmt(IntPtr db, IntPtr stmt);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern SQLiteErrorCode sqlite3_exec(IntPtr db, byte[] strSql, IntPtr pvCallback, IntPtr pvParam, out IntPtr errMsg);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_release_memory(int nBytes);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_get_autocommit(IntPtr db);

Added Tests/authorizer.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# authorizer.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 authorizer-1.1 {SQLiteConnection Authorize event} -setup {
  proc onAuthorize { sender e } {
    #
    # NOTE: Filter out the "noise" by allowing all standard
    #       events on the "sqlite_*" tables.
    #
    set noiseActionCodes [list \
        CreateTable CreateIndex Read Insert Update Delete]

    if {[$e ActionCode] in $noiseActionCodes && \
        [string match "sqlite_*" [$e Argument1]]} then {
      return
    }

    #
    # NOTE: Filter out all "non-primary" events to make the test
    #       results more deterministic in the face of different
    #       query plans.
    #
    if {[$e ActionCode] ne $::filter} then {
      return
    }

    #
    # NOTE: Record the authorizer arguments exactly as we received
    #       them.
    #
    lappend ::data [list \
        [$e UserData] [$e ActionCode] [$e Argument1] \
        [$e Argument2] [$e Database] [$e Context]]

    #
    # NOTE: Deny all attempts to create a table named "tDeny".
    #
    if {[$e ActionCode] eq "CreateTable" && \
        [$e Argument1] eq "tDeny"} then {
      $e ReturnCode Deny
    }
  }

  setupDb [set fileName authorizer-1.1.db]
} -body {
  set connection [getDbConnection]

  set callback onAuthorize
  object invoke $connection add_Authorize $callback

  set results [list]

  set sql [list \
    CreateTable       {CREATE TABLE t1(x);} \
    CreateIndex       {CREATE INDEX i1 ON t1(x);} \
    CreateTrigger     {CREATE TRIGGER tr1 BEFORE INSERT ON t1
                       BEGIN
                         SELECT RAISE(IGNORE);
                       END;} \
    CreateView        {CREATE VIEW v1 AS SELECT * FROM t1;} \
    CreateTempTable   {CREATE TEMPORARY TABLE t2(x);} \
    CreateTempIndex   {CREATE INDEX i2 ON t2(x);} \
    CreateTempTrigger {CREATE TEMPORARY TRIGGER tr2 BEFORE INSERT ON t2
                       BEGIN
                         SELECT RAISE(IGNORE);
                       END;} \
    CreateTempView    {CREATE TEMPORARY VIEW v2 AS SELECT * FROM t2;} \
    Pragma            {PRAGMA journal_mode=WAL;} \
    Function          {SELECT julianday('now');} \
    Read              {SELECT x FROM t1;} \
    Select            {SELECT * FROM t1;} \
    Insert            {INSERT INTO t1(x) VALUES(1);} \
    Update            {UPDATE t1 SET x = x - 1;} \
    Delete            {DELETE FROM t1;} \
    AlterTable        {ALTER TABLE t1 ADD COLUMN y;} \
    Reindex           {REINDEX t1;} \
    Analyze           {ANALYZE t1;} \
    DropTempView      {DROP VIEW v2;} \
    DropTempTrigger   {DROP TRIGGER tr2;} \
    DropTempIndex     {DROP INDEX i2;} \
    DropTempTable     {DROP TABLE t2;} \
    DropView          {DROP VIEW v1;} \
    DropTrigger       {DROP TRIGGER tr1;} \
    DropIndex         {DROP INDEX i1;} \
    DropTable         {DROP TABLE t1;} \
    Transaction       {BEGIN; SELECT 0; COMMIT;} \
    Savepoint         {SAVEPOINT s1; RELEASE SAVEPOINT s1;} \
    Attach            {ATTACH DATABASE ':memory:' AS d1;} \
    Detach            {DETACH DATABASE d1;} \
    CreateVtable      {CREATE VIRTUAL TABLE t3 USING fts4(x TEXT);} \
    DropVtable        {DROP TABLE t3;} \
    CreateTable       {CREATE TABLE tDeny(x);}]

  foreach {name value} $sql {
    set filter $name; set data [list]
    set code [catch {sql execute $db $value} result]
    set result [lindex [split [string map [list \r\n \n] $result] \n] 0]
    lappend results [list $name $data $code $result]
  }
  lappend results [isTableInDb tDeny]

  set results
} -cleanup {
  catch {object invoke $connection remove_Authorize $callback}
  catch {object removecallback $callback}

  cleanupDb $fileName

  freeDbConnection

  unset -nocomplain result code data filter value name sql results callback \
      connection db fileName

  rename onAuthorize ""
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{{CreateTable {{0 CreateTable t1 {} main {}}} 0 0} {CreateIndex {{0 CreateIndex\
i1 t1 main {}}} 0 0} {CreateTrigger {{0 CreateTrigger tr1 t1 main {}}} 0 0}\
{CreateView {{0 CreateView v1 {} main {}}} 0 0} {CreateTempTable {{0\
CreateTempTable t2 {} temp {}}} 0 0} {CreateTempIndex {{0 CreateTempIndex i2 t2\
temp {}}} 0 0} {CreateTempTrigger {{0 CreateTempTrigger tr2 t2 temp {}}} 0 0}\
{CreateTempView {{0 CreateTempView v2 {} temp {}}} 0 0} {Pragma {{0 Pragma\
journal_mode WAL {} {}}} 0 0} {Function {{0 Function {} julianday {} {}}} 0 0}\
{Read {{0 Read t1 x main {}}} 0 0} {Select {{0 Select {} {} {} {}}} 0 0}\
{Insert {{0 Insert t1 {} main {}}} 0 0} {Update {{0 Update t1 x main {}}} 0 0}\
{Delete {{0 Delete t1 {} main {}}} 0 0} {AlterTable {{0 AlterTable main t1 {}\
{}}} 0 0} {Reindex {{0 Reindex i1 {} main {}}} 0 0} {Analyze {{0 Analyze t1 {}\
main {}}} 0 0} {DropTempView {{0 DropTempView v2 {} temp {}}} 0 0}\
{DropTempTrigger {{0 DropTempTrigger tr2 t2 temp {}}} 0 0} {DropTempIndex {{0\
DropTempIndex i2 t2 temp {}}} 0 0} {DropTempTable {{0 DropTempTable t2 {} temp\
{}}} 0 0} {DropView {{0 DropView v1 {} main {}}} 0 0} {DropTrigger {{0\
DropTrigger tr1 t1 main {}}} 0 0} {DropIndex {{0 DropIndex i1 t1 main {}}} 0 0}\
{DropTable {{0 DropTable t1 {} main {}}} 0 0} {Transaction {{0 Transaction\
BEGIN {} {} {}} {0 Transaction COMMIT {} {} {}}} 0 0} {Savepoint {{0 Savepoint\
BEGIN s1 {} {}} {0 Savepoint RELEASE s1 {} {}}} 0 0} {Attach {{0 Attach\
:memory: {} {} {}}} 0 0} {Detach {{0 Detach d1 {} {} {}}} 0 0} {CreateVtable\
{{0 CreateVtable t3 fts4 main {}}} 0 0} {DropVtable {{0 DropVtable t3 fts4 main\
{}}} 0 0} {CreateTable {{0 CreateTable tDeny {} main {}}} 1\
{System.Data.SQLite.SQLiteException (0x80004005): authorization denied}} False}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/backup.eagle.
218
219
220
221
222
223
224
225
226
227


228
229
230
231
232
233
234
218
219
220
221
222
223
224



225
226
227
228
229
230
231
232
233







-
-
-
+
+







    cleanupDb $fileName(2)
    cleanupDb $fileName(1) memDb

    freeDbConnection memSource

    unset -nocomplain result results errors code index memSource dataSource \
        id memDb db fileName callbackResults
  } -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result [appendArgs \
  } -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result [appendArgs \
"^Ok System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} " \
[lindex $params(results) $i]]}
}

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

unset -nocomplain i params pages callback
Changes to Tests/basic.eagle.
94
95
96
97
98
99
100
101
102


103
104
105
106
107
108
109
94
95
96
97
98
99
100


101
102
103
104
105
106
107
108
109







-
-
+
+








  list $code [expr {$code == 0 ? "" : $error}]
} -cleanup {
  cleanupFile $fileName

  unset -nocomplain totalCount failureCount successCount code output \
      error fileName
} -constraints {eagle SQLite file_System.Data.SQLite.dll file_test.exe} \
-result {0 {}}}
} -constraints {eagle SQLite file_System.Data.SQLite.dll file_test.exe\
testExec} -result {0 {}}}

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

runTest {test data-1.2 {unit tests from the 'testlinq' project} -setup {
  #
  # NOTE: Re-copy the reference database file used for this unit test to the
  #       build directory in case it has been changed by a previous test run.
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150







-
+







} -cleanup {
  catch {object invoke Console OutputEncoding $savedEncoding}

  unset -nocomplain code output error savedEncoding encoding
} -constraints \
{eagle monoToDo SQLite file_System.Data.SQLite.dll\
file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db\
file_testlinq.out} -result {0 True {}}}
file_testlinq.out testExec} -result {0 True {}}}

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

runTest {test data-1.3 {SELECT scalar/reader, CREATE, INSERT} -setup {
  setupDb [set fileName data-1.3.db]
} -body {
  set result [list]
215
216
217
218
219
220
221
222
223
224
225



226
227
228
229
230
231
232
215
216
217
218
219
220
221




222
223
224
225
226
227
228
229
230
231







-
-
-
-
+
+
+







      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} GetReservedWords
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
System#Data#DataTable#\d+$}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 System#Data#DataTable#\d+$}}

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

runTest {test data-1.5 {GetSchema with ForeignKeys} -setup {
  setupDb [set fileName data-1.5.db]
} -body {
  sql execute $db {
302
303
304
305
306
307
308
309
310
311
312
313
314






315
316
317
318
319
320
321
301
302
303
304
305
306
307






308
309
310
311
312
313
314
315
316
317
318
319
320







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







        set rows
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result rows foreignKey foreignKeys results errors code \
      dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
\{\{main FK_t1_0_0 main t1 \{FOREIGN KEY\} False False 0 x main t2 \{\} 0 \{SET\
DEFAULT\} CASCADE NONE\} \{main FK_t2_0_0 main t2 \{FOREIGN KEY\} False False 0\
x main t3 \{\} 0 \{NO ACTION\} \{NO ACTION\} NONE\}\}$}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\{main FK_t1_0_0 main t1\
\{FOREIGN KEY\} False False 0 x main t2 \{\} 0 \{SET DEFAULT\} CASCADE NONE\}\
\{main FK_t2_0_0 main t2 \{FOREIGN KEY\} False False 0 x main t3 \{\} 0 \{NO\
ACTION\} \{NO ACTION\} NONE\}\}$}}

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

runTest {test data-1.6 {SQLITE_FCNTL_WIN32_AV_RETRY} -setup {
  setupDb [set fileName data-1.6.db]
} -body {
  set id [object invoke Interpreter.GetActive NextId]
405
406
407
408
409
410
411
412
413
414



415
416
417
418
419
420
421
422
404
405
406
407
408
409
410



411
412
413

414
415
416
417
418
419
420







-
-
-
+
+
+
-







    }
  }

  cleanupDb $fileName

  unset -nocomplain result count interval savedCount savedInterval results \
      errors code dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 True$}}
True$}}

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

runTest {test data-1.7 {properly closed database file (non-query)} -setup {
  set fileName data-1.7.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
462
463
464
465
466
467
468
469
470
471



472
473
474
475
476
477
478
479
460
461
462
463
464
465
466



467
468
469

470
471
472
473
474
475
476







-
-
-
+
+
+
-







        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result \
      [close [open $dataSource RDONLY 0 "" -share None]]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\} \{\}$}}
\{\} \{\}$}}

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

runTest {test data-1.8 {properly closed database file (reader #1)} -setup {
  set fileName data-1.8.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
522
523
524
525
526
527
528
529
530
531



532
533
534
535
536
537
538
539
519
520
521
522
523
524
525



526
527
528

529
530
531
532
533
534
535







-
-
-
+
+
+
-







        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result \
      [close [open $dataSource RDONLY 0 "" -share None]]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\} \{\}$}}
\{\} \{\}$}}

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

runTest {test data-1.9 {properly closed database file (reader #2)} -setup {
  set fileName data-1.9.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
584
585
586
587
588
589
590
591
592
593



594
595
596
597
598
599
600
601
580
581
582
583
584
585
586



587
588
589

590
591
592
593
594
595
596







-
-
-
+
+
+
-







        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result \
      [close [open $dataSource RDONLY 0 "" -share None]]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\} \{\}$}}
\{\} \{\}$}}

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

runTest {test data-1.10 {Changes property} -setup {
  setupDb [set fileName data-1.10.db]
} -body {
  set connection [getDbConnection]
886
887
888
889
890
891
892
893

894
895
896
897
898
899
900
881
882
883
884
885
886
887

888
889
890
891
892
893
894
895







-
+







          string kind,
          string formatString
          )
        {
          SQLiteConnectionStringBuilder builder =
              new SQLiteConnectionStringBuilder();

          builder.Add("Date Source", "test.db");
          builder.Add("Data Source", "test.db");
          builder.Add("DateTimeFormat", format);
          builder.Add("DateTimeKind", kind);
          builder.Add("DateTimeFormatString", formatString);

          return builder.ToString();
        }

928
929
930
931
932
933
934
935
936
937
938
939
940






941
942
943
944
945
946
947
923
924
925
926
927
928
929






930
931
932
933
934
935
936
937
938
939
940
941
942







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







      } result] : [set result ""]}] $result \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} GetConnectionString \
            Ticks Local yyyy-MM-dd
      } result] : [set result ""]}] $result
} -cleanup {
  unset -nocomplain result results errors code id
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{Date\
Source=test\.db\} 0 \{Date Source=test\.db;DateTimeFormat=(?:Default|ISO8601)\}\
0 \{Date Source=test\.db;DateTimeKind=Unspecified\} 0 \{Date\
Source=test\.db;DateTimeFormat=(?:Default|ISO8601);DateTimeKind=Utc\} 0 \{Date\
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{Data Source=test\.db\} 0\
\{Data Source=test\.db;DateTimeFormat=(?:Default|ISO8601)\} 0 \{Data\
Source=test\.db;DateTimeKind=Unspecified\} 0 \{Data\
Source=test\.db;DateTimeFormat=(?:Default|ISO8601);DateTimeKind=Utc\} 0 \{Data\
Source=test\.db;DateTimeFormat=Ticks;DateTimeKind=Local;DateTimeFormatString=yyyy-MM-dd\}$}}

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

runTest {test data-1.16 {SQLiteConnectionStringBuilder properties} -body {
  set id [object invoke Interpreter.GetActive NextId]

1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067












1068
1069
1070
1071
1072
1073
1074
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
1069







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







    }
  }

  set results
} -cleanup {
  unset -nocomplain propertyName propertyNames value key values keys result \
      results errors code id
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^System#CodeDom#Compiler#CompilerResults#\d+ Ok \{\} 0 \{, \} 0\
\{3, Version=3\} 0 \{Normal, Synchronous=Normal\} 0 \{True,\
UseUTF16Encoding=True\} 0 \{False, Pooling=False\} 0 \{True, BinaryGUID=True\}\
0 \{test\.db, Data Source=test\.db\} 0 \{test\.db, Uri=test\.db\} 0\
\{file:test.db, FullUri=file:test\.db\} 0 \{60, Default Timeout=60\} 0 \{False,\
Enlist=False\} 0 \{True, FailIfMissing=True\} 0 \{False, Legacy Format=False\}\
0 \{True, Read Only=True\} 0 \{secret, Password=secret\} 0 \{4096, Page\
Size=4096\} 0 \{1024, 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,\
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result \
{^System#CodeDom#Compiler#CompilerResults#\d+ Ok \{\} 0 \{, \} 0 \{3,\
Version=3\} 0 \{Normal, Synchronous=Normal\} 0 \{True, UseUTF16Encoding=True\}\
0 \{False, Pooling=False\} 0 \{True, BinaryGUID=True\} 0 \{test\.db, Data\
Source=test\.db\} 0 \{test\.db, Uri=test\.db\} 0 \{file:test.db,\
FullUri=file:test\.db\} 0 \{60, Default Timeout=60\} 0 \{False, Enlist=False\}\
0 \{True, FailIfMissing=True\} 0 \{False, Legacy Format=False\} 0 \{True, Read\
Only=True\} 0 \{secret, Password=secret\} 0 \{4096, Page Size=4096\} 0 \{1024,\
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}$}}

###############################################################################
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216



1217
1218
1219
1220
1221
1222
1223
1202
1203
1204
1205
1206
1207
1208



1209
1210
1211
1212
1213
1214
1215
1216
1217
1218







-
-
-
+
+
+







      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

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

runTest {test data-1.22 {SQLiteFunction collation exception} -setup {
  setupDb [set fileName data-1.22.db]
} -body {
  sql execute $db "CREATE TABLE t1(x TEXT);"
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300



1301
1302
1303
1304
1305
1306
1307
1286
1287
1288
1289
1290
1291
1292



1293
1294
1295
1296
1297
1298
1299
1300
1301
1302







-
-
-
+
+
+







      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 1\
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 1\
\{System\.Reflection\.TargetInvocationException: Exception has been thrown by\
the target of an invocation\. ---> System\.Data\.SQLite\.SQLiteException:\
interrupted.*$}}

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

runTest {test data-1.23 {LINQ SQL_CONSTRAINTCOLUMNS resource} -body {
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487






2488
2489
2490
2491
2492
2493
2494
2469
2470
2471
2472
2473
2474
2475







2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488







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







      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} DoTest false
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 1\
\{System\.Reflection\.TargetInvocationException: Exception has been thrown by\
the target of an invocation\. ---> System\.Data\.SQLite\.SQLiteException: SQL\
logic error or missing database
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 1 \{System\.Reflection\.TargetInvocationException: Exception has been\
thrown by the target of an invocation\. --->\
System\.Data\.SQLite\.SQLiteException: SQL logic error or missing database
no such function: MyRandom.*\} 0 (?:-)?\d+ 1\
\{System\.Reflection\.TargetInvocationException: Exception has been thrown by\
the target of an invocation\. ---> System\.Data\.SQLite\.SQLiteException: SQL\
logic error or missing database
no such function: MyRandom.*\}$}]}

###############################################################################
2526
2527
2528
2529
2530
2531
2532


















































































































































2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682







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










{SMALLINT Int16} {SMALLUINT UInt16} {STRING String} {TEXT String} {TIME\
DateTime} {TIMESTAMP DateTime} {TINYINT Byte} {TINYSINT SByte} {UINT UInt32}\
{UINT8 Byte} {UINT16 UInt16} {UINT32 UInt32} {UINT64 UInt64} {ULONG UInt64}\
{UNIQUEIDENTIFIER Guid} {UNSIGNEDINTEGER UInt64} {UNSIGNEDINTEGER8 Byte}\
{UNSIGNEDINTEGER16 UInt16} {UNSIGNEDINTEGER32 UInt32} {UNSIGNEDINTEGER64\
UInt64} {VARBINARY Binary} {VARCHAR AnsiString} {VARCHAR2 AnsiString} {YESNO\
Boolean}}}

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

runTest {test data-1.52 {totype extension} -setup {
  setupDb [set fileName data-1.52.db]
} -body {
  set connection [getDbConnection]
  set result [list]

  $connection EnableExtensions true
  $connection LoadExtension [getCoreBinaryFileName] sqlite3_totype_init

  lappend result [sql execute -execute scalar $db "SELECT tointeger('1');"]
  lappend result [sql execute -execute scalar $db "SELECT tointeger('1x');"]
  lappend result [sql execute -execute scalar $db "SELECT toreal('1.01');"]
  lappend result [sql execute -execute scalar $db "SELECT toreal('1.0x');"]

  set result
} -cleanup {
  freeDbConnection

  unset -nocomplain result connection

  cleanupDb $fileName

  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{1 {} 1.01 {}}}

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

runTest {test data-1.53 {regexp extension} -setup {
  setupDb [set fileName data-1.53.db]
} -body {
  unset -nocomplain pattern result

  set connection [getDbConnection]
  set result(1) [list]

  $connection EnableExtensions true
  $connection LoadExtension [getCoreBinaryFileName] sqlite3_regexp_init

  set pattern(1) {^\d+ [A-Z]{1,3}$}; # valid
  set pattern(2) {^\d+ [C]($}; # invalid

  lappend result(1) [catch {
    sql execute -execute scalar $db "SELECT REGEXP('$pattern(1)', '1 AB');"
  } result(2)] $result(2)

  lappend result(1) [catch {
    sql execute -execute scalar $db "SELECT REGEXP('$pattern(2)', '1 AB');"
  } result(2)] [string trim [lindex [split $result(2) \n] 1]]

  lappend result(1) [catch {
    sql execute -execute scalar $db "SELECT '1 AB' REGEXP '$pattern(1)';"
  } result(2)] $result(2)

  lappend result(1) [catch {
    sql execute -execute scalar $db "SELECT '1 AB' REGEXP '$pattern(2)';"
  } result(2)] [string trim [lindex [split $result(2) \n] 1]]

  lappend result(1) [catch {
    sql execute -execute scalar $db "SELECT REGEXP('$pattern(1)', '2');"
  } result(2)] $result(2)

  lappend result(1) [catch {
    sql execute -execute scalar $db "SELECT REGEXP('$pattern(2)', '2');"
  } result(2)] [string trim [lindex [split $result(2) \n] 1]]

  lappend result(1) [catch {
    sql execute -execute scalar $db "SELECT '2' REGEXP '$pattern(1)';"
  } result(2)] $result(2)

  lappend result(1) [catch {
    sql execute -execute scalar $db "SELECT '2' REGEXP '$pattern(2)';"
  } result(2)] [string trim [lindex [split $result(2) \n] 1]]

  set result(1)
} -cleanup {
  freeDbConnection

  unset -nocomplain pattern result connection

  cleanupDb $fileName

  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{0 1 1 {unmatched '('} 0 1 1 {unmatched '('} 0 0 1 {unmatched '('} 0 0 1\
{unmatched '('}}}

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

reportSQLiteResources $test_channel

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

runTest {test data-1.54 {SQLiteConnection.ReleaseMemory method} -setup {
  setupDb [set fileName data-1.54.db]
} -body {
  set result [list]

  set nFree 0; set resetOk false; set nLargest 0
  set code [object invoke \
      System.Data.SQLite.SQLiteConnection ReleaseMemory \
      -1 true true nFree resetOk nLargest]

  lappend result [list $code $nFree $resetOk $nLargest]

  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(RANDOMBLOB(1048576));"

  set nFree 0; set resetOk false; set nLargest 0
  set code [object invoke \
      System.Data.SQLite.SQLiteConnection ReleaseMemory \
      -1 true true nFree resetOk nLargest]

  tputs $test_channel [appendArgs \
      "---- memory released by SQLite... " $nFree " bytes\n"]

  lappend result [list $code $nFree $resetOk $nLargest]

  cleanupDb $fileName
  checkForSQLiteDirectories $test_channel true

  set nFree 0; set resetOk false; set nLargest 0
  set code [object invoke \
      System.Data.SQLite.SQLiteConnection ReleaseMemory \
      -1 true true nFree resetOk nLargest]

  tputs $test_channel [appendArgs \
      "---- largest free SQLite heap block... " $nLargest " bytes\n"]

  lappend result [list $code $nFree $resetOk $nLargest]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain nLargest resetOk nFree code result db fileName
} -constraints {eagle monoBug28 configuration.Release command.sql compile.DATA\
SQLite System.Data.SQLite} -match regexp -result {^\{Busy 0 False 0\} \{Busy\
\d+ False 0\} \{Ok 0 True \d+\}$}}

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

reportSQLiteResources $test_channel

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

unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \
    testExeFile testLinqExeFile northwindEfDbFile testLinqOutFile

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/common.eagle.
228
229
230
231
232
233
234































































































































































235
236
237
238
239
240
241
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400







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







        #
        # NOTE: No path is available, return an empty string.  This point
        #       should not be reached.
        #
        return ""
      }
    }

    proc isMixedModeAssembly { fileName {varName ""} } {
      #
      # NOTE: First, make sure the test suite infrastructure is allowed to
      #       use the [exec] command.
      #
      if {![info exists ::no(exec)] && ![info exists ::no(corFlags)]} then {
        #
        # NOTE: If the location of CorFlags is present in the environment,
        #       use it; otherwise assume it is in the PATH.
        #
        set corFlags [expr {
          [info exists ::env(CorFlags)] ? $::env(CorFlags) : "CorFlags"
        }]

        #
        # NOTE: Attempt to execute CorFlags on the specified file.
        #
        if {[catch {
          exec -- $corFlags [file nativename $fileName]
        } exec] == 0} then {
          #
          # NOTE: If requested by our caller, attempt to determine the
          #       platform for the specified file as well.
          #
          if {[string length $varName] > 0} then {
            #
            # NOTE: Store the platform in the named variable in the
            #       context of our caller.
            #
            upvar 1 $varName platform

            #
            # NOTE: Attempt to extract the PE line from the captured
            #       output.  If this value is "PE32" or "PE32+", the
            #       assembly file is 32-bit or 64-bit, respectively;
            #       otherwise, its type is unknown.
            #
            set pattern {^PE        : (PE32|PE32\+)\s+$}

            if {[regexp -line -- $pattern $exec dummy pe32]} then {
              #
              # HACK: This [switch] assumes that 32-bit executables are
              #       always x86 and that 64-bit executables are always
              #       x64.
              #
              switch -exact -- $pe32 {
                PE32 {
                  set platform Win32
                }
                PE32+ {
                  set platform x64
                }
                default {
                  set platform ""
                }
              }
            } else {
              set platform ""
            }
          }

          #
          # NOTE: Attempt to extract the ILONLY line from the captured
          #       output.  If this value is zero, the specified file must
          #       be a mixed-mode assembly; otherwise, it contains only
          #       managed components.
          #
          set pattern {^ILONLY    : (0|1)\s+$}

          if {![regexp -line -- $pattern $exec dummy ilOnly]} then {
            return false
          }

          if {!$ilOnly} then {
            return true
          }
        }
      }

      #
      # NOTE: If the test suite cannot use [exec] or execution of CorFlags
      #       failed, return false.
      #
      return false
    }

    proc isBuildAvailable { native directory {varName ""} } {
      #
      # NOTE: Build the fully qualified file name for the primary assembly
      #       containing the System.Data.SQLite managed components.  It
      #       should be noted that this assembly file may also contain the
      #       native components, if a native build is in use.
      #
      set fileName [file nativename [file join $directory \
          System.Data.SQLite.dll]]

      if {![file exists $fileName]} then {
        return false
      }

      #
      # NOTE: Attempt to automatically detect if the primary assembly
      #       contains any native components, if necessary.
      #
      if {[string length $native] == 0} then {
        if {[string length $varName] > 0} then {
          upvar 1 $varName $varName
        }

        set native [isMixedModeAssembly $fileName $varName]
      }

      #
      # NOTE: If the primary assembly also contains the native components,
      #       we have everything we need.
      #
      if {$native} then {
        return true
      }

      #
      # NOTE: Build the fully qualified file name for the interop assembly
      #       containing the System.Data.SQLite native components.  If this
      #       file exists, we should have everything we need.
      #
      set fileName [file nativename [file join $directory \
          SQLite.Interop.dll]]

      if {[file exists $fileName]} then {
        return true
      }

      #
      # NOTE: Build the fully qualified file name for the SQLite core
      #       library.  If this file exists, we should have everything we
      #       need.
      #
      set fileName [file nativename [file join $directory \
          sqlite3.dll]]

      if {[file exists $fileName]} then {
        return true
      }

      #
      # NOTE: One or more native components needed by System.Data.SQLite
      #       are missing.
      #
      return false
    }

    proc isReleaseAvailable { directory {varName ""} } {
      if {[string length $varName] > 0} then {
        upvar 1 $varName $varName
      }

      return [isBuildAvailable "" $directory $varName]
    }

    proc joinBuildDirectory { native path year platform configuration } {
      #
      # NOTE: Figure out and then return the fully qualified path to the build
      #       directory based on all the arguments provided by our caller.
      #
      if {$native} then {
313
314
315
316
317
318
319




















320
321
322
323
324
325
326
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







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







        #
        set native [hasRuntimeOption native]

        return [joinBuildDirectory $native [getBuildBaseDirectory] \
            [getBuildYear] [getBuildPlatform $native] [getBuildConfiguration]]
      }
    }

    proc getReleaseVersion {} {
      #
      # NOTE: Figure out the release version for use with the build directory
      #       when checking for available releases.
      #
      if {[info exists ::release_version] && \
          [string length $::release_version] > 0} then {
        #
        # NOTE: The release version has been overridden; therefore, use it
        #       verbatim.
        #
        return $::release_version
      } else {
        #
        # NOTE: No release version is available, return an empty string.
        #
        return ""
      }
    }

    proc getBuildFileName { fileName } {
      #
      # NOTE: Returns the specified file name as if it were located in the
      #       build directory, discarding any directory information present
      #       in the file name as provided by our caller.
      #
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
739
740
741
742
743
744
745
746













































































747
748
749
750








751
752
753
754
755
756
757
758
759
760
761
762
763
764








765
766
767














































768
769
770
771
772
773
774
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919

920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938

939
940
941
942
943
944
945
946






947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987




988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
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
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
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







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








+
+
+
+
+
+
+
+


-
+
+
+

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






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




+
+
+
+
+
+
+
+














+
+
+
+
+
+
+
+



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







      #       the SQLite native library; otherwise, this procedure will simply
      #       always return zero.
      #
      return [expr {[haveConstraint System.Data.SQLite] && \
          [haveConstraint SQLite]}]
    }

    proc matchMachine { platform } {
      #
      # NOTE: An empty string for the platform means that the build is not
      #       [primarily] a native build; therefore, it always matches.
      #
      if {[string length $platform] == 0} then {
        return true
      }

      #
      # NOTE: Does the specified platform match up to the current process?
      #
      if {$platform eq [machineToPlatform $::tcl_platform(machine)]} then {
        return true
      }

      #
      # NOTE: The specified platform does not match up with the platform
      #       for the current process.
      #
      return false
    }

    proc checkForSQLiteBuilds { channel } {
    proc checkForSQLiteBuilds { channel {select false} } {
      #
      # NOTE: Check for every possible valid combination of values used when
      #       locating out the build output directory, showing each available
      #       build variation along the way.
      #
      foreach native [list false true] {
        foreach year [getBuildYears] {
          foreach configuration [getBuildConfigurations] {
            #
            # NOTE: Figure out the effective build platform.  This is
            #       based on whether or not a [primarily] native build
            #       is being used.  For [primarily] non-native builds,
            #       this will be an empty string.
            #
            set platform [getBuildPlatform $native]

            tputs $channel [appendArgs \
                "---- checking for System.Data.SQLite build \"" [expr \
                {$native ? "native/" : ""}] $year / $configuration "\"... "]
                {$native ? "native/" : ""}] [expr {[string length \
                $platform] > 0 ? [appendArgs $platform /] : ""}] $year \
                / $configuration "\"... "]

            #
            # NOTE: Build the fully qualified directory where the necessary
            #       components for System.Data.SQLite should be found.
            #
            set fileName [file nativename [file join [joinBuildDirectory \
                $native [getBuildBaseDirectory] $year [getBuildPlatform \
                $native] $configuration] System.Data.SQLite.dll]]

            if {[file exists $fileName]} then {
              tputs $channel yes\n
            set directory [joinBuildDirectory $native \
                [getBuildBaseDirectory] $year $platform $configuration]

            #
            # NOTE: Do the necessary files exist?  Currently, no other steps
            #       are taken to verify this build is actually viable.
            #
            if {[isBuildAvailable $native $directory]} then {
              #
              # NOTE: When in "select" mode, automatically select the first
              #       available build of System.Data.SQLite and then return
              #       immediately.
              #
              if {$select && [matchMachine $platform]} then {
                #
                # NOTE: Manually override all the build directory selection
                #       related test settings in order to force this build
                #       of System.Data.SQLite to be used.
                #
                object invoke Interpreter.GetActive [expr {$native ? \
                    "AddRuntimeOption" : "RemoveRuntimeOption"}]  native

                set ::test_year $year
                set ::test_platform $platform
                set ::test_configuration $configuration

                tputs $channel [appendArgs \
                    "yes, selected (" [expr {$native ? "native/" : ""}] \
                    [expr {[string length $platform] > 0 ? [appendArgs \
                    $platform /] : ""}] $year / $configuration ")\n"]

                return true
              } else {
                tputs $channel yes\n
              }
            } else {
              tputs $channel no\n
            }
          }
        }
      }
    }

    proc checkForSQLite { channel } {
      tputs $channel "---- checking for core SQLite library... "

      return false
    }

    proc checkForSQLiteReleases { channel {select false} } {
      #
      # NOTE: Check for past releases of System.Data.SQLite in the directory
      #       contained in the "System.Data.SQLite" environment variable, if
      #       present.
      #
      if {[info exists ::env(System.Data.SQLite)] && \
          [string length $::env(System.Data.SQLite)] > 0} then {
        #
        # NOTE: Build the fully qualified directory where the necessary
        #       components for System.Data.SQLite should be found.
        #
        set directory [file nativename [file join \
            $::env(System.Data.SQLite) [getReleaseVersion]]]

        tputs $channel [appendArgs \
            "---- checking for System.Data.SQLite release \"" \
            $directory "\"... "]

        if {[isReleaseAvailable $directory platform]} then {
          if {[string length $platform] == 0} then {
            set platform unknown
          }

          if {$select && [matchMachine $platform]} then {
            set ::build_directory $directory

            tputs $channel [appendArgs "yes, selected (" $platform ")\n"]

            return true
          } else {
            tputs $channel [appendArgs "yes (" $platform ")\n"]
          }
        } else {
          tputs $channel no\n

          foreach path [lsort -decreasing [file list $directory *]] {
            if {[file exists $path] && [file isdirectory $path]} then {
              tputs $channel [appendArgs \
                  "---- checking for System.Data.SQLite release \"" \
                  $path "\"... "]

              if {[isReleaseAvailable $path platform]} then {
                if {[string length $platform] == 0} then {
                  set platform unknown
                }

                if {$select && [matchMachine $platform]} then {
                  set ::build_directory $path

                  tputs $channel [appendArgs "yes, selected (" $platform ")\n"]

                  return true
                } else {
                  tputs $channel [appendArgs "yes (" $platform ")\n"]
                }
              } else {
                tputs $channel no\n
              }
            }
          }
        }
      } else {
        tputs $channel [appendArgs \
            "---- environment variable \"System.Data.SQLite\" is not " \
            "set, skipping check for releases...\n"]
      }

      return false
    }

    proc checkForSQLiteLibrary { channel } {
      tputs $channel "---- checking for SQLite core library... "

      if {[catch {
              object invoke -flags +NonPublic System.Data.SQLite.SQLite3 \
              SQLiteVersion} version] == 0} then {
        #
        # NOTE: Check if the returned version was null.  If so, make it easy
        #       to spot.
        #
        if {[string length $version] == 0} then {
          set version null
        }

        #
        # NOTE: Attempt to query the Fossil source identifier for the SQLite
        #       core library.
        #
        if {[catch {
                object invoke -flags +NonPublic System.Data.SQLite.SQLite3 \
                SQLiteSourceId} sourceId]} then {
          #
          # NOTE: We failed to query the Fossil source identifier.
          #
          set sourceId unknown
        }

        #
        # NOTE: Check if the returned Fossil source identifier was null.  If
        #       so, make it easy to spot.
        #
        if {[string length $sourceId] == 0} then {
          set sourceId null
        }

        #
        # NOTE: Yes, the SQLite core library appears to be available.
        #
        addConstraint SQLite

        tputs $channel [appendArgs "yes (" $version " " $sourceId ")\n"]
      } else {
        tputs $channel no\n
      }
    }

    proc checkForSQLiteInterop { channel } {
      tputs $channel "---- checking for SQLite interop assembly... "

      if {[catch {
              object invoke -flags +NonPublic System.Data.SQLite.SQLite3 \
              InteropVersion} version] == 0} then {
        #
        # NOTE: Check if the returned version was null.  If so, make it easy
        #       to spot.
        #
        if {[string length $version] == 0} then {
          set version null
        }

        #
        # NOTE: Attempt to query the Fossil source identifier for the SQLite
        #       core library.
        #
        if {[catch {
                object invoke -flags +NonPublic System.Data.SQLite.SQLite3 \
                InteropSourceId} sourceId]} then {
          #
          # NOTE: We failed to query the Fossil source identifier.
          #
          set sourceId unknown
        }

        #
        # NOTE: Check if the returned Fossil source identifier was null.  If
        #       so, make it easy to spot.
        #
        if {[string length $sourceId] == 0} then {
          set sourceId null
        }

        #
        # NOTE: Yes, the SQLite interop assembly appears to be available.
        #
        addConstraint SQLiteInterop

        tputs $channel [appendArgs "yes (" $version " " $sourceId ")\n"]
      } else {
        tputs $channel no\n
      }
    }

915
916
917
918
919
920
921






















922
923
924
925
926
927
928
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330







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







    proc isMemoryDb { fileName } {
      #
      # NOTE: Is the specified database file name really an in-memory database?
      #
      return [expr {$fileName eq ":memory:" || \
          [string range $fileName 0 12] eq "file::memory:"}]
    }

    proc isTableInDb { name {varName db} } {
      #
      # NOTE: Refer to the specified variable (e.g. "db") in the context of our
      #       caller.  It contains the database connection handle that will be
      #       used to execute the query used to determine if the named table is
      #       present in that database.
      #
      upvar 1 $varName db

      #
      # NOTE: Execute the SQL query against the sqlite_master table to check if
      #       the named table is present and return non-zero if it is.
      #
      return [expr {[sql execute -execute scalar $db \
          "SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = ?;" \
          [list param1 String $name]] > 0}]
    }

    proc trimSql { sql } {
      return [regsub -all -- {\s+} [string trim $sql] " "]
    }

    proc executeSql { sql {execute none} {fileName ""} } {
      if {[string length $fileName] == 0} then {set fileName :memory:}
      setupDb $fileName "" "" "" "" "" false false false false memDb

      try {
        return [sql execute -execute $execute $memDb $sql]
1287
1288
1289
1290
1291
1292
1293
1294

1295
1296
1297
1298
1299
1300
1301
1689
1690
1691
1692
1693
1694
1695

1696
1697
1698
1699
1700
1701
1702
1703







-
+







            #
            object foreach -alias pair \
                [object invoke -flags +NonPublic $e Interpreter.connections] {
              #
              # NOTE: Attempt to cancel any SQL queries in progress on this
              #       database connection.
              #
              if {[catch {$pair Value.Cancel} error] != 0} then {
              if {[catch {$pair Value.Cancel} error]} then {
                tputs $::test_channel [appendArgs \n \
                    "==== WARNING: failed to cancel query for connection \"" \
                    [$pair Key] "\", error: " \n\t $error \n]
              }
            }
          }
        }}
1797
1798
1799
1800
1801
1802
1803












1804
1805
1806
1807
1808
1809
1810
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224







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







            tryDeleteAssembly System.Data.SQLite.dll
            removeConstraint file_System.Data.SQLite.dll

            tryDeleteAssembly System.Data.SQLite.Linq.dll
            removeConstraint file_System.Data.SQLite.Linq.dll
          }

          #
          # NOTE: Check for the "autoSelect" runtime option.  If present,
          #       attempt to automatically select the first available
          #       build (or "release") of SQLite and System.Data.SQLite
          #       for use with the test suite.
          #
          if {[hasRuntimeOption autoSelect]} then {
            if {![checkForSQLiteBuilds $::test_channel true]} then {
              checkForSQLiteReleases $::test_channel true
            }
          }

          #
          # NOTE: Skip trying to verify the build directory if we are so
          #       instructed; otherwise, make sure it actually exists or
          #       halt the entire testing process if it does not exist.
          #
          if {![info exists ::no(verifyBuildDirectory)]} then {
            #
1913
1914
1915
1916
1917
1918
1919
1920

































1921
1922
1923
1924
1925
1926
1927


1928
1929

1930
1931
1932
1933
1934
1935
1936
1937
1938






1939
1940
1941
1942
1943
1944
1945
2327
2328
2329
2330
2331
2332
2333

2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372

2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385

2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398







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






-
+
+


+








-
+
+
+
+
+
+







          tputs $::test_channel \
              "---- define constants for \"System.Data.SQLite\"... "

          if {[catch {object invoke -flags +NonPublic \
                  System.Data.SQLite.SQLite3 DefineConstants} \
                  defineConstants] == 0} then {
            tputs $::test_channel [appendArgs [formatList [lsort \
                $defineConstants]] \n]
                $defineConstants] <none>] \n]
          } else {
            tputs $::test_channel unknown\n
          }
        }

        catch {
          tputs $::test_channel \
              "---- source version of \"System.Data.SQLite.dll\"... "

          if {[catch {object invoke -flags +NonPublic \
                  System.Data.SQLite.SQLiteConnection ProviderVersion} \
                  version] == 0} then {
            if {[string length $version] == 0} then {
              set version null
            }
            tputs $::test_channel [appendArgs $version \n]
          } else {
            tputs $::test_channel unknown\n
          }
        }

        catch {
          tputs $::test_channel \
              "---- source checkout of \"System.Data.SQLite.dll\"... "

          if {[catch {object invoke -flags +NonPublic \
                  System.Data.SQLite.SQLiteConnection ProviderSourceId} \
                  sourceId] == 0} then {
            if {[string length $sourceId] == 0} then {
              set sourceId null
            }
            tputs $::test_channel [appendArgs $sourceId \n]
          } else {
            tputs $::test_channel unknown\n
          }
        }

        #
        # NOTE: Check the available builds of SQLite and System.Data.SQLite.
        # NOTE: Check the available builds (and "releases") of SQLite and
        #       System.Data.SQLite.
        #
        checkForSQLiteBuilds $::test_channel
        checkForSQLiteReleases $::test_channel

        #
        # NOTE: Now, we need to know if the SQLite core library is available
        #       (i.e. because the managed-only System.Data.SQLite assembly can
        #       load without it; however, it cannot do anything useful without
        #       it).  If we are using the mixed-mode assembly and we already
        #       found it (above), this should always succeed.
        #
        checkForSQLite $::test_channel
        checkForSQLiteLibrary $::test_channel

        #
        # NOTE: Check if the SQLite interop assembly is available.
        #
        checkForSQLiteInterop $::test_channel

        #
        # NOTE: Check the SQLite database and temporary directories.
        #
        checkForSQLiteDirectories $::test_channel

        #
2021
2022
2023
2024
2025
2026
2027
2028

2029
2030
2031
2032
2033
2034
2035
2474
2475
2476
2477
2478
2479
2480

2481
2482
2483
2484
2485
2486
2487
2488







-
+







        #
        reportSQLiteResources $::test_channel

        #
        # NOTE: Show the active test constraints.
        #
        tputs $::test_channel [appendArgs "---- constraints: " \
            [formatList [lsort [getConstraints]]] \n]
            [formatList [lsort [getConstraints]] <none>] \n]

        #
        # NOTE: Save the test constraints for use by threads created in this
        #       application domain.  This is necessary because all the Eagle
        #       "test context" information is per-thread.
        #
        if {![info exists ::test_constraints]} then {
Changes to Tests/installer.eagle.
150
151
152
153
154
155
156
157
158



159
160
161
162
163
164
165
150
151
152
153
154
155
156


157
158
159
160
161
162
163
164
165
166







-
-
+
+
+







  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testInstallVs2005LogFile]]] : $error}]
} -cleanup {
  cleanupFile $fileName

  unset -nocomplain wow64 is64 code output error fileName
} -constraints {eagle administrator buildYear.2005 visualStudio2005\
System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\
file_System.Data.SQLite.dll file_Installer_Test_Vs2005.log} -result {0 True}}
System.Data.SQLite.dll_v2.0.50727 file_Installer.exe testExec\
file_System.Data.SQLite.dll file_SQLite.Designer.dll\
file_Installer_Test_Vs2005.log} -result {0 True}}

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

runTest {test installer-1.2 {uninstaller tool / Visual Studio 2005} -setup {
  set fileName [file join [getTemporaryPath] [file tail [string map [list \
      .log [appendArgs _ [pid] .log]] $testUninstallVs2005LogFile]]]

187
188
189
190
191
192
193
194
195



196
197
198
199
200
201
202
188
189
190
191
192
193
194


195
196
197
198
199
200
201
202
203
204







-
-
+
+
+







  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testUninstallVs2005LogFile]]] : $error}]
} -cleanup {
  cleanupFile $fileName

  unset -nocomplain wow64 is64 code output error fileName
} -constraints {eagle administrator buildYear.2005 visualStudio2005\
System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\
file_System.Data.SQLite.dll file_Uninstaller_Test_Vs2005.log} -result {0 True}}
System.Data.SQLite.dll_v2.0.50727 file_Installer.exe testExec\
file_System.Data.SQLite.dll file_SQLite.Designer.dll\
file_Uninstaller_Test_Vs2005.log} -result {0 True}}

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

runTest {test installer-1.3 {installer tool / Visual Studio 2008} -setup {
  set fileName [file join [getTemporaryPath] [file tail [string map [list \
      .log [appendArgs _ [pid] .log]] $testInstallVs2008LogFile]]]

224
225
226
227
228
229
230
231

232
233

234
235
236
237
238
239
240
226
227
228
229
230
231
232

233
234

235
236
237
238
239
240
241
242







-
+

-
+







  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testInstallVs2008LogFile]]] : $error}]
} -cleanup {
  cleanupFile $fileName

  unset -nocomplain wow64 is64 code output error fileName
} -constraints {eagle administrator buildYear.2008 visualStudio2008\
System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\
System.Data.SQLite.dll_v2.0.50727 file_Installer.exe testExec\
file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
file_Installer_Test_Vs2008.log} -result {0 True}}
file_SQLite.Designer.dll file_Installer_Test_Vs2008.log} -result {0 True}}

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

runTest {test installer-1.4 {uninstaller tool / Visual Studio 2008} -setup {
  set fileName [file join [getTemporaryPath] [file tail [string map [list \
      .log [appendArgs _ [pid] .log]] $testUninstallVs2008LogFile]]]

262
263
264
265
266
267
268
269

270
271

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

271
272

273
274
275
276
277
278
279
280







-
+

-
+







  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testUninstallVs2008LogFile]]] : $error}]
} -cleanup {
  cleanupFile $fileName

  unset -nocomplain wow64 is64 code output error fileName
} -constraints {eagle administrator buildYear.2008 visualStudio2008\
System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\
System.Data.SQLite.dll_v2.0.50727 file_Installer.exe testExec\
file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
file_Uninstaller_Test_Vs2008.log} -result {0 True}}
file_SQLite.Designer.dll file_Uninstaller_Test_Vs2008.log} -result {0 True}}

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

runTest {test installer-1.5 {installer tool / Visual Studio 2010} -setup {
  set fileName [file join [getTemporaryPath] [file tail [string map [list \
      .log [appendArgs _ [pid] .log]] $testInstallVs2010LogFile]]]

300
301
302
303
304
305
306
307

308
309

310
311
312
313
314
315
316
302
303
304
305
306
307
308

309
310

311
312
313
314
315
316
317
318







-
+

-
+







  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testInstallVs2010LogFile]]] : $error}]
} -cleanup {
  cleanupFile $fileName

  unset -nocomplain wow64 is64 code output error fileName
} -constraints {eagle administrator buildYear.2010 visualStudio2010\
System.Data.SQLite.dll_v4.0.30319 file_Installer.exe\
System.Data.SQLite.dll_v4.0.30319 file_Installer.exe testExec\
file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
file_Installer_Test_Vs2010.log} -result {0 True}}
file_SQLite.Designer.dll file_Installer_Test_Vs2010.log} -result {0 True}}

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

runTest {test installer-1.6 {uninstaller tool / Visual Studio 2010} -setup {
  set fileName [file join [getTemporaryPath] [file tail [string map [list \
      .log [appendArgs _ [pid] .log]] $testUninstallVs2010LogFile]]]

338
339
340
341
342
343
344
345

346
347

348
349
350
351
352
353
354
340
341
342
343
344
345
346

347
348

349
350
351
352
353
354
355
356







-
+

-
+







  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testUninstallVs2010LogFile]]] : $error}]
} -cleanup {
  cleanupFile $fileName

  unset -nocomplain wow64 is64 code output error fileName
} -constraints {eagle administrator buildYear.2010 visualStudio2010\
System.Data.SQLite.dll_v4.0.30319 file_Installer.exe\
System.Data.SQLite.dll_v4.0.30319 file_Installer.exe testExec\
file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
file_Uninstaller_Test_Vs2010.log} -result {0 True}}
file_SQLite.Designer.dll file_Uninstaller_Test_Vs2010.log} -result {0 True}}

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

runTest {test installer-1.7 {installer tool / Visual Studio 2012} -setup {
  set fileName [file join [getTemporaryPath] [file tail [string map [list \
      .log [appendArgs _ [pid] .log]] $testInstallVs2012LogFile]]]

376
377
378
379
380
381
382
383

384
385

386
387
388
389
390
391
392
378
379
380
381
382
383
384

385
386

387
388
389
390
391
392
393
394







-
+

-
+







  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testInstallVs2012LogFile]]] : $error}]
} -cleanup {
  cleanupFile $fileName

  unset -nocomplain wow64 is64 code output error fileName
} -constraints {eagle administrator buildYear.2012 visualStudio2012\
System.Data.SQLite.dll_v4.0.30319 file_Installer.exe\
System.Data.SQLite.dll_v4.0.30319 file_Installer.exe testExec\
file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
file_Installer_Test_Vs2012.log} -result {0 True}}
file_SQLite.Designer.dll file_Installer_Test_Vs2012.log} -result {0 True}}

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

runTest {test installer-1.8 {uninstaller tool / Visual Studio 2012} -setup {
  set fileName [file join [getTemporaryPath] [file tail [string map [list \
      .log [appendArgs _ [pid] .log]] $testUninstallVs2012LogFile]]]

414
415
416
417
418
419
420
421

422
423

424
425
426
427
428
429
430
431
432
433
434
435
436
416
417
418
419
420
421
422

423
424

425
426
427
428
429
430
431
432
433
434
435
436
437
438







-
+

-
+













  list $code [expr {$code == 0 ? [string equal [readFile $fileName] \
      [subst -nobackslashes [readFile $testUninstallVs2012LogFile]]] : $error}]
} -cleanup {
  cleanupFile $fileName

  unset -nocomplain wow64 is64 code output error fileName
} -constraints {eagle administrator buildYear.2012 visualStudio2012\
System.Data.SQLite.dll_v4.0.30319 file_Installer.exe\
System.Data.SQLite.dll_v4.0.30319 file_Installer.exe testExec\
file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
file_Uninstaller_Test_Vs2012.log} -result {0 True}}
file_SQLite.Designer.dll file_Uninstaller_Test_Vs2012.log} -result {0 True}}

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

unset -nocomplain testUninstallVs2012LogFile testUninstallVs2010LogFile \
    testUninstallVs2008LogFile testUninstallVs2005LogFile \
    testInstallVs2012LogFile testInstallVs2010LogFile \
    testInstallVs2008LogFile testInstallVs2005LogFile sqliteDesignerDllFile \
    installerExeFile systemDataSQLiteLinqDllFile systemDataSQLiteDllFile

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

runSQLiteTestEpilogue
runTestEpilogue
Added Tests/settings.before.mistachkin.eagle.












1
2
3
4
5
6
7
8
9
10
11
12
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# settings.before.mistachkin.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

if {[info exists ::env(TEST_ALL)]} then {
  object invoke Interpreter.GetActive AddRuntimeOption noPoolCounts
}
Added Tests/settings.stress.mistachkin.eagle.















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# settings.stress.mistachkin.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

# set count(1) 10;        # Workload iteration count (i.e. within a run).
# set count(2) 200;       # Workload iteration delay, in milliseconds.
# set count(3) 10000;     # Workload "small" data chunk size, in bytes.
# set count(5) 209715200; # Maximum heap memory to exclude at one time.
# set exitOnFail true;    # Halt testing and exit process on test failure?
# set noTrace true;       # Disable SQLite trace logging to a file?
Changes to Tests/stress.eagle.
1424
1425
1426
1427
1428
1429
1430
1431

1432
1433
1434
1435
1436
1437
1438
1424
1425
1426
1427
1428
1429
1430

1431
1432
1433
1434
1435
1436
1437
1438







-
+







  rename setupLogging ""

  unset -nocomplain result thread index workload priority noWorkload \
      priorities srcDb db fileName compiled options count times logFileName \
      logListener event timeout connection indicators iterations exitOnFail \
      coTaskMem noTrace failures status
} -time true -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -result {0}}
System.Data.SQLite compileCSharp} -result {0}}

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

#
# NOTE: Report after test.
#
checkForSQLiteDirectories $test_channel
Changes to Tests/thread.eagle.
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468







-
+







      [getSQLiteHandleCounts $test_channel] \
      [reportSQLiteResources $test_channel]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id db fileName
} -time true -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -match regexp -result [appendArgs "^Ok\
System.Data.SQLite compileCSharp} -match regexp -result [appendArgs "^Ok\
System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{\\d+ \\d+ " $count(1) \
"\\} \\{\\} \\{" $handle_counts "\\} " $memory_used \$]}

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

unset -nocomplain count

Changes to Tests/tkt-00f86f9739.eagle.
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93







-
+







  }

  set result
} -cleanup {
  unset -nocomplain code output error result value
} -constraints \
{eagle monoToDo defineConstant.System.Data.SQLite.USE_INTEROP_DLL\
defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS SQLite\
defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS SQLite testExec\
file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll file_testlinq.exe\
file_northwindEF.db} -result {0 {} 0 {DRACD OLDWO RATTC} 0 {ALFKI CACTU CHOPS\
FOLKO GALED KOENE LILAS MAGAA MAISD OCEAN RANCH SAVEA THECR} 0 {} 0 {} 0 {} 0\
{}}}

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

Changes to Tests/tkt-201128cc88.eagle.
90
91
92
93
94
95
96
97
98
99



100
101
102
103
104
105
90
91
92
93
94
95
96



97
98
99
100
101
102
103
104
105







-
-
-
+
+
+






      [sql execute -execute scalar $db "SELECT Base64(CAST(NULL AS BLOB));"] \
      [sql execute -execute scalar $db "SELECT Base64(CAST('' AS BLOB));"] \
      [sql execute -execute scalar $db "SELECT Base64(CAST('foo' AS BLOB));"]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}\
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}\
System#Data#SQLite#SQLiteConnection#\d+ \{\} \{\} Zm9v$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-343d392b51.eagle.
186
187
188
189
190
191
192
193
194
195



196
197
198
199
200
201
202
186
187
188
189
190
191
192



193
194
195
196
197
198
199
200
201
202







-
-
-
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName; unset -nocomplain db fileName
  cleanupDb $otherFileName

  unset -nocomplain result code results errors i sql otherTable otherDbName \
      otherDataSource dataSource id otherFileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
glob -result {* System.Data.DBConcurrencyException: *}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match glob -result {*\
System.Data.DBConcurrencyException: *}}

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

runTest {test tkt-343d392b51-2.2 {SQLiteDataAdapter update success} -setup {
  setupDb [set fileName tkt-343d392b51-2.2.db] "" JulianDay
  set otherFileName tkt-343d392b51-2.2-otherDb.db
} -body {
292
293
294
295
296
297
298
299
300
301



302
303
304
305
306
307
308
292
293
294
295
296
297
298



299
300
301
302
303
304
305
306
307
308







-
-
-
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName; unset -nocomplain db fileName
  cleanupDb $otherFileName

  unset -nocomplain result code results errors i sql otherTable otherDbName \
      otherDataSource dataSource id otherFileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

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

runTest {test tkt-343d392b51-3.1 {attached database, same table name} -setup {
  setupDb [set fileName tkt-343d392b51-3.1.db]
  set otherFileName tkt-343d392b51-3.1-otherDb.db
} -body {
428
429
430
431
432
433
434
435
436
437



438
439
440
441
442
428
429
430
431
432
433
434



435
436
437
438
439
440
441
442







-
-
-
+
+
+





      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName; unset -nocomplain db fileName
  cleanupDb $otherFileName

  unset -nocomplain result code results errors i sql otherTable otherDbName \
      otherDataSource dataSource id otherFileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-3aa50d8413.eagle.
72
73
74
75
76
77
78
79
80
81



82
83
84
85
86
72
73
74
75
76
77
78



79
80
81
82
83
84
85
86







-
-
-
+
+
+





      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-48a6b8e4ca.eagle.
74
75
76
77
78
79
80
81
82
83



84
85
86
87
88
74
75
76
77
78
79
80



81
82
83
84
85
86
87
88







-
-
-
+
+
+





      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-4a791e70ab.eagle.
67
68
69
70
71
72
73
74
75
76



77
78
79
80
81
67
68
69
70
71
72
73



74
75
76
77
78
79
80
81







-
-
-
+
+
+





      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-59edc1018b.eagle.
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93







-
+







  }

  set result
} -cleanup {
  unset -nocomplain code output error result value
} -constraints \
{eagle monoToDo defineConstant.System.Data.SQLite.USE_INTEROP_DLL\
defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS SQLite\
defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS SQLite testExec\
file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll file_testlinq.exe\
file_northwindEF.db} -result {0 {} 0 {FURIB GALED GODOS LAZYK LINOD PRINI REGGC\
WOLZA} 0 {} 0 ERNSH 0 {} 0 {AROUT BSBEV CONSH EASTC NORTS SEVES} 0 {}}}

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

unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \
Changes to Tests/tkt-6434e23a0f.eagle.
72
73
74
75
76
77
78
79
80
81



82
83
84
85
86
72
73
74
75
76
77
78



79
80
81
82
83
84
85
86







-
-
-
+
+
+





      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-6c6ecccc5f.eagle.
67
68
69
70
71
72
73
74
75
76



77
78
79
80
81
82
67
68
69
70
71
72
73



74
75
76

77
78
79
80
81







-
-
-
+
+
+
-





      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}
\{\}$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-72905c9a77.eagle.
270
271
272
273
274
275
276
277
278


279
280
281
282
283
284
285
270
271
272
273
274
275
276


277
278
279
280
281
282
283
284
285







-
-
+
+







      } result] : [set result ""]}] [string map [list \r\n \n] $result]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors dataSource fileName
} -constraints [fixConstraints {eagle monoBug28 configuration.Release\
!defineConstant.System.Data.SQLite.INTEROP_LOG command.sql compile.DATA\
SQLite System.Data.SQLite}] -match regexp -result [appendArgs "^Ok\
System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{" [string repeat \
SQLite System.Data.SQLite compileCSharp}] -match regexp -result [appendArgs \
"^Ok System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{" [string repeat \
"SQLite message \\(0\\): TEST $id
" [expr {4 * [info processors]}]] "\\}\$"]}

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

unset -nocomplain id

Changes to Tests/tkt-7e3fa93744.eagle.
124
125
126
127
128
129
130
131
132
133



134
135
136
137
138
124
125
126
127
128
129
130



131
132
133
134
135
136
137
138







-
-
-
+
+
+





      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 8$}}
} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 8$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-8b7d179c3c.eagle.
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91







-
+







      lappend result [string trim $error]
    }
  }

  set result
} -cleanup {
  unset -nocomplain code output error result pageSize
} -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll\
} -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll testExec\
file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} \
-result {0 {} 0 {DRACD RATTC OLDWO GALED LILAS MAGAA ALFKI CHOPS SAVEA KOENE\
MAISD FOLKO CACTU OCEAN RANCH THECR GOURL GROSR SUPRD HUNGO ISLAT QUICK HUNGC\
GREAL LEHMS RICSU ERNSH WILMK LINOD TRAIH SIMOB OTTIK SPLIR MORGK FOLIG FURIB\
PRINI AROUT BSBEV CONSH EASTC NORTS SEVES BERGS VICTE BOLID FISSA ROMEY BLAUS\
BONAP MEREP ANATR ANTON CENTC PERIC TORTU FRANK TOMSP DUMON FRANR WARTH PARIS\
SPECD LONEP THEBI REGGC VINET WELLI HANAR QUEDE RICAR PICCO HILAA LETSS COMMI\
Changes to Tests/tkt-996d13cd87.eagle.
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297







-
+







    cleanupDb $fileName

    unset -nocomplain result results errors code sql dataSource id \
        poolCounts havePoolCounts fileName

    rename getPoolCounts ""
  } -constraints {eagle monoBug28 command.sql compile.DATA\
SQLite System.Data.SQLite} -match regexp -result {^Ok\
SQLite System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \d+ \{\} True True$}}
}

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

unset -nocomplain count pooling i

Added Tests/tkt-9ba9346f75.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# tkt-9ba9346f75.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 tkt-9ba9346f75-1.1 {AutoCommit property} -setup {
  setupDb [set fileName tkt-9ba9346f75-1.1.db]
} -body {
  set connection [getDbConnection]

  set result [list]

  lappend result [object invoke $connection AutoCommit]; # True

  sql execute $db "CREATE TABLE t1(x);"
  lappend result [object invoke $connection AutoCommit]; # True

  sql execute $db "INSERT INTO t1 (x) VALUES(1);"
  lappend result [object invoke $connection AutoCommit]; # True

  sql execute $db "BEGIN TRANSACTION;"
  lappend result [object invoke $connection AutoCommit]; # False

  sql execute $db "INSERT INTO t1 (x) VALUES(1);"
  lappend result [object invoke $connection AutoCommit]; # False

  sql execute $db "COMMIT;"
  lappend result [object invoke $connection AutoCommit]; # True

  set result
} -cleanup {
  cleanupDb $fileName

  freeDbConnection

  unset -nocomplain result connection db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{True True True False False True}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-ae5267b863.eagle.
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157







-
+







        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id db fileName
} -constraints [fixConstraints {eagle monoBug28 command.sql compile.DATA\
SQLite System.Data.SQLite !mda\
SQLite System.Data.SQLite !mda compileCSharp\
!defineConstant.System.Data.SQLite.INTEROP_LEGACY_CLOSE}] -match regexp \
-result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-ccfa69fc32.eagle.
77
78
79
80
81
82
83
84

85
86
87
88

89
90
91
92
93
94
95
77
78
79
80
81
82
83

84
85
86
87

88
89
90
91
92
93
94
95







-
+



-
+







      lappend result [string trim $error]
    }
  }

  set result
} -cleanup {
  unset -nocomplain code output error result add
} -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll\
} -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll testExec\
file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} -match \
glob -result {0 {1581 1730 1833 2116 2139} 0 {System.Data.UpdateException: *\
---> System.Data.SQLite.SQLiteException: constraint failed
PRIMARY KEY must be unique
UNIQUE constraint failed: Territories.TerritoryID
*} 0 {1 2 3 4 5 6 7 8 9 10 1576 1577 1578 1579 1580 1581 1730 1833 2116 2139}}}

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

unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \
    testLinqExeFile northwindEfDbFile

Changes to Tests/tkt-e06c4caff3.eagle.
29
30
31
32
33
34
35
36

37
38

39
40
41
42
43
44
45
29
30
31
32
33
34
35

36
37

38
39
40
41
42
43
44
45







-
+

-
+







      [list param1 Double [set NaN [object invoke Double NaN]]]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain NaN db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-returnCodes 1 -match regexp -result [string map [list \n \r\n]\
-returnCodes 1 -match regexp -result [string map [list \n \r\n] \
{^System\.Data\.SQLite\.SQLiteException \(0x80004005\): constraint failed
t1\.x may not be NULL
NOT NULL constraint failed: t1\.x
.*$}]}

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

runTest {test tkt-e06c4caff3-1.2 {NaN to NULL} -setup {
  setupDb [set fileName tkt-e06c4caff3-1.2.db]
} -body {
Changes to Tests/tkt-e1b2e0f769.eagle.
119
120
121
122
123
124
125
126
127
128
129




130
131
132
133
134
135
119
120
121
122
123
124
125




126
127
128
129
130
131
132
133
134
135







-
-
-
-
+
+
+
+







  set result1
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result2 result1 code results errors sql table dataSource \
      id x db fileName
} -constraints \
[fixConstraints {eagle monoBug28 command.sql compile.DATA SQLite\
!defineConstant.System.Data.SQLite.CHECK_STATE System.Data.SQLite}] -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 3 Ok\
} -constraints [fixConstraints {eagle monoBug28 command.sql compile.DATA SQLite\
!defineConstant.System.Data.SQLite.CHECK_STATE System.Data.SQLite\
compileCSharp}] -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 3 Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 0$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-e30b820248.eagle.
104
105
106
107
108
109
110
111
112
113


114
115
116
117
118
119
120
104
105
106
107
108
109
110



111
112
113
114
115
116
117
118
119







-
-
-
+
+







        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result \
      [reportSQLiteResources $test_channel true]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql name dataSource id fileName
} -constraints \
{eagle logFile monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result [appendArgs "^Ok\
} -constraints {eagle logFile monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result [appendArgs "^Ok\
System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{\\} " $memory_used \$]}

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

for {set i 2} {$i < 5} {incr i} {
  set memory_used [reportSQLiteResources $test_channel true]

259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272







-
+







        [reportSQLiteResources $test_channel true]
  } -cleanup {
    cleanupDb $fileName

    unset -nocomplain result code results errors sql name dataSource id \
        fileName
  } -constraints {eagle logFile monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -match regexp -result [appendArgs "^Ok\
System.Data.SQLite compileCSharp} -match regexp -result [appendArgs "^Ok\
System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{\\} " $memory_used \$]}
}

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

unset -nocomplain i

Added Tests/tkt-f8dbab8baf.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# tkt-f8dbab8baf.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 tkt-f8dbab8baf-1.1 {SchemaOnly with CREATE TABLE} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.1.db]
} -body {
  sql execute -execute reader -format none -behavior SchemaOnly $db \
      "CREATE TABLE t1(x);"

  isTableInDb t1
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{False}}

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

runTest {test tkt-f8dbab8baf-1.2 {SchemaOnly with ALTER TABLE} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.2.db]
} -body {
  sql execute $db "CREATE TABLE t1(x);"

  sql execute -execute reader -format none -behavior SchemaOnly $db \
      "ALTER TABLE t1 RENAME TO t2;"

  list [isTableInDb t1] [isTableInDb t2]
} -cleanup {
  cleanupDb $fileName

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

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

runTest {test tkt-f8dbab8baf-1.3 {SchemaOnly with DROP TABLE} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.3.db]
} -body {
  sql execute $db "CREATE TABLE t1(x);"

  sql execute -execute reader -format none -behavior SchemaOnly $db \
      "DROP TABLE t1;"

  isTableInDb t1
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{True}}

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

runTest {test tkt-f8dbab8baf-1.4 {CREATE/SELECT success} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.4.db]
} -body {
  sql execute -execute reader $db {
    CREATE TABLE t1(x);
    INSERT INTO t1 (x) VALUEs(1);
    SELECT x FROM t1;
  }

  list [isTableInDb t1] \
      [expr {[info exists rows(count)] ? $rows(count) : -1}] \
      [expr {[info exists rows(names)] ? $rows(names) : ""}]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain rows db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{True 1 x}}

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

runTest {test tkt-f8dbab8baf-1.5 {SchemaOnly CREATE/SELECT success} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.5.db]
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUEs(1);"
  sql execute -execute reader -behavior SchemaOnly $db "SELECT x FROM t1;"

  list [isTableInDb t1] \
      [expr {[info exists rows(count)] ? $rows(count) : -1}] \
      [expr {[info exists rows(names)] ? $rows(names) : ""}]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain rows db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{True 0 x}}

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

runTest {test tkt-f8dbab8baf-1.6 {SchemaOnly CREATE/SELECT failure} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.6.db]
} -body {
  sql execute -execute reader -format none -behavior SchemaOnly $db \
      "CREATE TABLE t1(x); SELECT x FROM t1;"

  list [isTableInDb t1] \
      [expr {[info exists rows(count)] ? $rows(count) : -1}] \
      [expr {[info exists rows(names)] ? $rows(names) : ""}]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain rows db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-returnCodes 1 -match regexp -result [string map [list \n \r\n] \
{^System\.Data\.SQLite\.SQLiteException \(0x80004005\): SQL logic error or\
missing database
no such table: t1.*$}]}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/version.eagle.
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39







-
+







#
# NOTE: For these unit tests to be useful and accurate, the following version
#       numbers must be manually kept synchronized with the version numbers for
#       the source code files, the built binaries, and the release packages.
#
set version(major)             1
set version(minor)             0
set version(build)            89; # NOTE: Incremented with each release.
set version(build)            90; # NOTE: Incremented with each release.
set version(revision)          0

###############################################################################
# ********************* END VOLATILE VERSION INFORMATION **********************
###############################################################################

#
164
165
166
167
168
169
170












































171
172
173
174
175
176
177
164
165
166
167
168
169
170
171
172
173
174
175
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







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







  $assemblyName Version.ToString
} -cleanup {
  unset -nocomplain assemblyName
} -constraints {eagle file_testlinq.exe} -result $version(full)}

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

runTest {test version-1.11 {SQLiteVersion} -body {
  object invoke System.Data.SQLite.SQLiteConnection SQLiteVersion
} -constraints {eagle SQLite System.Data.SQLite} -match regexp -result \
{^\d+\.\d+\.\d+(?:\.\d+)?$}}

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

runTest {test version-1.12 {SQLiteSourceId} -body {
  object invoke System.Data.SQLite.SQLiteConnection SQLiteSourceId
} -constraints {eagle SQLite System.Data.SQLite} -match regexp -result \
{^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [0-9a-f]{40}$}}

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

runTest {test version-1.13 {InteropVersion} -body {
  object invoke System.Data.SQLite.SQLiteConnection InteropVersion
} -constraints {eagle SQLiteInterop System.Data.SQLite} -result $version(full)}

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

runTest {test version-1.14 {InteropSourceId} -body {
  object invoke System.Data.SQLite.SQLiteConnection InteropSourceId
} -constraints {eagle SQLiteInterop System.Data.SQLite} -match regexp -result \
{^[0-9a-f]{40} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} UTC$}}

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

runTest {test version-1.15 {ProviderVersion} -body {
  object invoke System.Data.SQLite.SQLiteConnection ProviderVersion
} -constraints {eagle System.Data.SQLite} -result $version(full)}

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

runTest {test version-1.16 {ProviderSourceId} -body {
  #
  # NOTE: The ProviderSourceId property value may be null, which
  #       would result in an empty string being returned here.
  #
  object invoke System.Data.SQLite.SQLiteConnection ProviderSourceId
} -constraints {eagle System.Data.SQLite} -match regexp -result \
{^(?:|[0-9a-f]{40} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} UTC)$}}

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

set patterns [list \
    [appendArgs Version= [string map [list . \\.] $version(full)] ,] \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
332
333
334
335
336
337
338

339
340
341
342
343
344
345
346







-
+







  set constraint [string map [list / _ \\ _] $fileName]
  set fileName [file join $root_path $fileName]

  if {![haveConstraint [appendArgs file_ $constraint]]} then {
    checkForFile $test_channel $fileName $constraint
  }

  runTest {test [appendArgs version-1.11. $i] \
  runTest {test [appendArgs version-1.17. $i] \
      [appendArgs "pattern {" $pattern "} in file \"" $fileName \"] -body {
    regexp -- $pattern [readFile $fileName]
  } -constraints [list eagle [appendArgs file_ $constraint]] -result {1}}
}

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

Changes to Tests/vtab.eagle.
99
100
101
102
103
104
105
106
107


108
109
110
111
112
113
114
99
100
101
102
103
104
105


106
107
108
109
110
111
112
113
114







-
-
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
{^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

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

runTest {test vtab-1.2.1 {IEnumerable virtual table} -setup {
  set fileName vtab-1.2.1.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
204
205
206
207
208
209
210
211
212
213




214
215
216
217
218
219
220
204
205
206
207
208
209
210



211
212
213
214
215
216
217
218
219
220
221







-
-
-
+
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 \{one two three 4 5\.0 Error \{SQL logic error or missing database
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{one two three 4 5\.0 Error\
\{SQL logic error or missing database
virtual table "t\d+" is read-only\}\}$}]}

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

runTest {test vtab-1.2.2 {IEnumerable virtual table} -setup {
  set fileName vtab-1.2.2.db
} -body {
314
315
316
317
318
319
320
321
322
323




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



322
323
324
325
326
327
328
329
330
331
332







-
-
-
+
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 \{one two three 4 5\.0 Error \{SQL logic error or missing database
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{one two three 4 5\.0 Error\
\{SQL logic error or missing database
virtual table "t\d+" is read-only\}\}$}]}

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

runTest {test vtab-1.3.1 {IEnumerable<T> virtual table} -setup {
  set fileName vtab-1.3.1.db
} -body {
422
423
424
425
426
427
428
429
430
431




432
433
434
435
436
437
438
424
425
426
427
428
429
430



431
432
433
434
435
436
437
438
439
440
441







-
-
-
+
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 \{1 2 3 4 5 Error \{SQL logic error or missing database
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{1 2 3 4 5 Error \{SQL\
logic error or missing database
virtual table "t\d+" is read-only\}\}$}]}

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

runTest {test vtab-1.3.2 {IEnumerable<T> virtual table} -setup {
  set fileName vtab-1.3.2.db
} -body {
533
534
535
536
537
538
539
540
541
542




543
544
545
546
547
548
549
536
537
538
539
540
541
542



543
544
545
546
547
548
549
550
551
552
553







-
-
-
+
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 \{1 2 3 4 5 Error \{SQL logic error or missing database
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{1 2 3 4 5 Error \{SQL\
logic error or missing database
virtual table "t\d+" is read-only\}\}$}]}

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

runTest {test vtab-1.4 {virtual table function support} -setup {
  set fileName vtab-1.4.db
} -body {
784
785
786
787
788
789
790
791
792
793




794
795
796
797
798
799
800
788
789
790
791
792
793
794



795
796
797
798
799
800
801
802
803
804
805







-
-
-
+
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 \{\{\} b25l \{SQL logic error or missing database
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\{\} b25l \{SQL logic\
error or missing database
unable to use function Base64 in the requested context\} \{SQL logic error or\
missing database
no such function: Base65\}\}$}]}

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

runTest {test vtab-1.5 {virtual table function support} -setup {
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046




1047
1048
1049
1050
1051
1052
1053
1042
1043
1044
1045
1046
1047
1048



1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059







-
-
-
+
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 \{\{\} b25l \{SQL logic error or missing database
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\{\} b25l \{SQL logic\
error or missing database
(?:unable to use function Base64 in the requested context|need exactly one\
argument, got 3)\} \{SQL logic error or missing database
no such function: Base65\}\}$}]}

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

runTest {test vtab-1.6 {virtual table rename support} -setup {
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225



1226
1227
1228
1229
1230
1231
1232
1222
1223
1224
1225
1226
1227
1228



1229
1230
1231
1232
1233
1234
1235
1236
1237
1238







-
-
-
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 \{\{\} t\d+ \{\} x\d+\}$}]}
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\{\} t\d+ \{\} x\d+\}$}]}

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

runTest {test vtab-1.7 {virtual table xBestIndex marshalling (1)} -setup {
  set fileName vtab-1.7.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325




1326
1327
1328
1329
1330
1331
1332
1322
1323
1324
1325
1326
1327
1328



1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339







-
-
-
+
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 \{0 5 two three one 5\.0 4\}$}]}
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{0 5 two three one 5\.0\
4\}$}]}

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

runTest {test vtab-1.8 {virtual table xBestIndex marshalling (2)} -setup {
  set fileName vtab-1.8.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426



1427
1428
1429
1430
1431
1432
1433
1424
1425
1426
1427
1428
1429
1430



1431
1432
1433
1434
1435
1436
1437
1438
1439
1440







-
-
-
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 \{0 5 one three\}$}]}
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{0 5 one three\}$}]}

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

runTest {test vtab-1.9 {IEnumerable virtual table w/large byte array} -setup {
  set fileName vtab-1.9.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504



1505
1506
1507
1508
1509
1510
1511
1502
1503
1504
1505
1506
1507
1508



1509
1510
1511
1512
1513
1514
1515
1516
1517
1518







-
-
-
+
+
+







      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -time true -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 (?:-)?\d+$}]}
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 (?:-)?\d+$}]}

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

runTest {test vtab-1.10 {virtual table xRowId uniqueness} -setup {
  set fileName vtab-1.10.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602





1603
1604
1605
1606
1607
1599
1600
1601
1602
1603
1604
1605




1606
1607
1608
1609
1610
1611
1612
1613
1614
1615







-
-
-
-
+
+
+
+
+





      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite\
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -match regexp -result \
[string map [list \n \r\n] {^Ok System#CodeDom#Compiler#CompilerResults#\d+\
\{\} 0 \{0 4294967296 4294967296 8589934592 8589934592 12884901888 12884901888\
17179869184 17179869184 21474836480 21474836480 25769803776 25769803776\}$}]}
defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE compileCSharp} -match \
regexp -result [string map [list \n \r\n] {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{0 4294967296 4294967296\
8589934592 8589934592 12884901888 12884901888 17179869184 17179869184\
21474836480 21474836480 25769803776 25769803776\}$}]}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to exclude_src.txt.
14
15
16
17
18
19
20


21
22
23
24
25
26
27

28
29
30
31
32
33
34
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37







+
+







+







bin/*
Doc/Output/*
Externals/Eagle/bin/Eagle.dll
Externals/Eagle/bin/EagleShell.exe
Externals/Eagle/bin/SQLite.Interop.*
Externals/Eagle/bin/sqlite3.*
Externals/Eagle/bin/System.*
Externals/Eagle/bin/x64/*
Externals/Eagle/bin/x86/*
Externals/Eagle/lib/Eagle1.0/embed.eagle
Externals/Eagle/lib/Eagle1.0/init.eagle
Externals/Eagle/lib/Eagle1.0/pkgIndex.eagle
Externals/Eagle/lib/Eagle1.0/pkgIndex.tcl
Externals/Eagle/lib/Eagle1.0/safe.eagle
Externals/Eagle/lib/Eagle1.0/shell.eagle
Externals/Eagle/lib/Eagle1.0/test.eagle
Externals/Eagle/lib/Eagle1.0/word.tcl
Externals/Eagle/lib/Test1.0/constraints.eagle
Externals/Eagle/lib/Test1.0/epilogue.eagle
Externals/Eagle/lib/Test1.0/pkgIndex.eagle
Externals/Eagle/lib/Test1.0/pkgIndex.tcl
Externals/Eagle/lib/Test1.0/prologue.eagle
Externals/HtmlHelp/*
Externals/MSVCPP/*
Changes to readme.htm.
1
2
3
4
5
6
7
8
9


10
11
12
13
14
15
16
1
2
3
4
5
6
7


8
9
10
11
12
13
14
15
16







-
-
+
+







<!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.89.0 September XX, 2013 <font color="red">(release scheduled)</font><br />
Using <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.8.1</a><br />
Version 1.0.90.0 January XX, 2014 <font color="red">(release scheduled)</font><br />
Using <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.8.2</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="http://system.data.sqlite.org/">http://system.data.sqlite.org/</a><br />
Legacy versions:&nbsp;<a href="http://sqlite.phxsoftware.com/">http://sqlite.phxsoftware.com/</a><br />
<br />
The current development version can be downloaded from <a href="http://system.data.sqlite.org/index.html/timeline?y=ci">
http://system.data.sqlite.org/index.html/timeline?y=ci</a>
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+







app.config file:<br />
<pre>
&lt;configuration&gt;
    &lt;system.data&gt;
        &lt;DbProviderFactories&gt;
            &lt;remove invariant="System.Data.SQLite" /&gt;
            &lt;add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite"
                 type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.89.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /&gt;
                 type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.90.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /&gt;
        &lt;/DbProviderFactories&gt;
    &lt;/system.data&gt;
&lt;/configuration&gt;
</pre>
<p>
See the help documentation for further details on implementing both version-specific
(GAC enabled) and version independent DBProviderFactories support.
183
184
185
186
187
188
189
190

191
192
193














194
195
196
197

198


199



200
201
202
203
204
205
206
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







-
+


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




+

+
+

+
+
+







it to extend its functionality, but the core engine's source is not changed.</p>
<p>
</p>

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

<p>
    <b>1.0.89.0 - September XX, 2013 <font color="red">(release scheduled)</font></b>
    <b>1.0.90.0 - January XX, 2014 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.8.1</a>.</li>
    <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.8.2</a>.</li>
    <li>Add experimental support for the native regexp extension.</li>
    <li>Never create a new connection wrapper in the SQLiteConnection.Shutdown method.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class.</li>
    <li>Add memory leak detection to the test project for the .NET Compact Framework.</li>
    <li>Add SQLITE_ENABLE_MEMORY_MANAGEMENT compile-time option to the interop assembly.</li>
    <li>Better handling of non-error log messages from the SQLite core library. Pursuant to [44df10ea90].</li>
</ul>
<p>
    <b>1.0.89.0 - October 28, 2013</b>
</p>
<ul>
    <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_1.html">SQLite 3.8.1</a>.</li>
    <li>Add AutoCommit property to the SQLiteConnection class. Fix for [9ba9346f75].</li>
    <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for [3113734605].</li>
    <li>Check the result of sqlite3_column_name function against NULL.</li>
    <li>Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.</li>
    <li>Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for [aba4549801].</li>
    <li>Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter.</li>
    <li>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Make sure the database cannot be changed by a query when the CommandBehavior.SchemaOnly flag is used. Fix for [f8dbab8baf].&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Fix bug in <a href="http://sourceforge.net/projects/ndoc3/">NDoc3</a> that was preventing some of the MSDN documentation links from working.</li>
    <li>Include the XML documentation files in the NuGet packages. Fix for [5970d5b0a6].</li>
    <li>Add InteropVersion, InteropSourceId, ProviderVersion, and ProviderSourceId properties to the SQLiteConnection class.</li>
    <li>Add experimental support for interfacing with the authorizer callback in the SQLite core library.</li>
    <li>Add experimental support for the native totype extension.</li>
</ul>
<p>
    <b>1.0.88.0 - August 7, 2013</b>
</p>
<ul>
    <li>Various fixes to managed virtual table integration infrastructure.</li>
    <li>Implement workaround for an incorrect PROCESSOR_ARCHITECTURE being reported. Fix for [9ac9862611].</li>
Changes to test/AssemblyInfo.cs.
34
35
36
37
38
39
40
41
42


34
35
36
37
38
39
40


41
42







-
-
+
+
// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.89.0")]
[assembly: AssemblyFileVersion("1.0.89.0")]
[assembly: AssemblyVersion("1.0.90.0")]
[assembly: AssemblyFileVersion("1.0.90.0")]
Changes to test/app.config.
1
2
3
4
5

6
7
8
1
2
3
4

5
6
7
8




-
+



<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.89.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.90.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
    </DbProviderFactories>
  </system.data>
</configuration>
Changes to testce/AssemblyInfo.cs.
34
35
36
37
38
39
40
41
42


43
34
35
36
37
38
39
40


41
42
43







-
-
+
+

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.89.0")]
// [assembly: AssemblyFileVersion("1.0.89.0")]
[assembly: AssemblyVersion("1.0.90.0")]
// [assembly: AssemblyFileVersion("1.0.90.0")]

Changes to testce/TestCases.cs.
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16








+







/********************************************************
 * 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!
 ********************************************************/

using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data;
using System.Data.SQLite;
using System.Threading;

namespace test
{
69
70
71
72
73
74
75

76
77
78
79
80
81
82
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84







+







      return String.Compare(param1, param2, true);
    }
  }

  internal sealed class TestCases
  {
    internal Form1 frm;
    internal IDictionary<string, long> statistics;

    private string connectionString;
    private DbConnection cnn;
    private string sql;
    private bool autoClose;
    private bool isolatedSql;
    private int total;
96
97
98
99
100
101
102





103


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118






























































119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139



140
141
142
143
144
145
146
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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







+
+
+
+
+
-
+
+















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
















+


-


+
+
+







        this.sql = sql;
        this.autoClose = autoExit;
        this.isolatedSql = isolatedSql;
    }

    internal bool Succeeded()
    {
        //
        // NOTE: Did all tests pass [without leaking any memory]?
        //
        long sqlBytes;

        return (failed == 0) && (passed == total);
        return (failed == 0) && (passed == total) && ((statistics == null) ||
            !statistics.TryGetValue("MemoryUsed", out sqlBytes) || (sqlBytes == 0));
    }

    private static string FormatString(string value)
    {
        if (value == null)
            return "(null)";

        if (value.Length == 0)
            return "(empty)";

        if (value.Trim().Length == 0)
            return "(whitespace)";

        return value;
    }

    private void WriteMemoryStatistics(
        bool forceFullCollection
        )
    {
        long clrBytes = GC.GetTotalMemory(false);
        SQLiteConnection.GetMemoryStatistics(ref statistics);
        if (statistics != null) statistics["ClrUsedBefore"] = clrBytes;

        if (frm != null)
        {
            frm.WriteLine("\r\nMemory in use by the CLR before collection: " +
                clrBytes.ToString() + " bytes");

            if (statistics != null)
            {
                long sqlBytes;

                if (statistics.TryGetValue("MemoryUsed", out sqlBytes))
                {
                    frm.WriteLine("Current SQLite memory usage before collection: " +
                        sqlBytes.ToString() + " bytes");
                }

                if (statistics.TryGetValue("MemoryHighwater", out sqlBytes))
                {
                    frm.WriteLine("Maximum SQLite memory usage before collection: " +
                        sqlBytes.ToString() + " bytes");
                }
            }
        }

        if (forceFullCollection)
        {
            clrBytes = GC.GetTotalMemory(true);
            SQLiteConnection.GetMemoryStatistics(ref statistics);
            if (statistics != null) statistics["ClrUsedAfter"] = clrBytes;

            if (frm != null)
            {
                frm.WriteLine("\r\nMemory in use by the CLR after collection: " +
                    clrBytes.ToString() + " bytes");

                if (statistics != null)
                {
                    long sqlBytes;

                    if (statistics.TryGetValue("MemoryUsed", out sqlBytes))
                    {
                        frm.WriteLine("Current SQLite memory usage after collection: " +
                            sqlBytes.ToString() + " bytes");
                    }

                    if (statistics.TryGetValue("MemoryHighwater", out sqlBytes))
                    {
                        frm.WriteLine("Maximum SQLite memory usage after collection: " +
                            sqlBytes.ToString() + " bytes");
                    }
                }
            }
        }
    }

    internal void Run()
    {
      frm = new Form1();
      frm.Show();

      frm.WriteLine(String.Format("\r\nTest connection string:\r\n\r\n{0}",
          FormatString(connectionString)));

      frm.WriteLine(String.Format("\r\nTest initialization SQL:\r\n\r\n{0}",
          FormatString(sql)));

      Type type = cnn.GetType();
      frm.WriteLine("\r\nBeginning Test on " + type.ToString());

      SQLiteConnection cnn2 = cnn as SQLiteConnection;

      if (cnn2 != null)
      {
          cnn2 = null;
          frm.WriteLine("SQLite v" + SQLiteConnection.SQLiteVersion +
              " [" + SQLiteConnection.SQLiteSourceId + "]");

          WriteMemoryStatistics(false);
          frm.WriteLine(String.Empty);
      }

      total++;
      try { CreateTable(cnn); frm.WriteLine("SUCCESS - CreateTable"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - CreateTable"); failed++; }

      total++;
228
229
230
231
232
233
234






235
236
237
238
239
240
241
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320







+
+
+
+
+
+







      catch (Exception) { frm.WriteLine("FAIL - MultipleThreadStress"); failed++; }

      total++;
      try { DropTable(cnn); frm.WriteLine("SUCCESS - DropTable"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - DropTable"); failed++; }

      frm.WriteLine("\r\nTests Finished.");

      if (cnn2 != null)
          cnn2.Close();

      WriteMemoryStatistics(true);

      frm.WriteLine(String.Format("\r\nCounts: {0} total, {1} passed, {2} failed", total, passed, failed));
      frm.WriteLine(String.Format("Result: {0}", Succeeded() ? "SUCCESS" : "FAILURE"));

      if (autoClose)
          frm.Close();
    }

Changes to testlinq/2008/App.config.
1
2
3
4
5
6

7
8
9
10
11
12
1
2
3
4
5

6
7
8
9
10
11
12





-
+






<?xml version="1.0"?>
<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.89.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.90.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
    </DbProviderFactories>
  </system.data>
  <connectionStrings>
    <add name="northwindEFEntities" connectionString="metadata=res://*/NorthwindModel2008.csdl|res://*/NorthwindModel2008.ssdl|res://*/NorthwindModel2008.msl;provider=System.Data.SQLite;provider connection string=&quot;data source=.\northwindEF.db&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>
Changes to testlinq/2010/App.config.
1
2
3
4
5
6

7
8
9
10
11
12
1
2
3
4
5

6
7
8
9
10
11
12





-
+






<?xml version="1.0"?>
<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.89.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.90.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
    </DbProviderFactories>
  </system.data>
  <connectionStrings>
    <add name="northwindEFEntities" connectionString="metadata=res://*/NorthwindModel2010.csdl|res://*/NorthwindModel2010.ssdl|res://*/NorthwindModel2010.msl;provider=System.Data.SQLite;provider connection string=&quot;data source=.\northwindEF.db&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>
Changes to testlinq/2012/App.config.
1
2
3
4
5
6

7
8
9
10
11
12
1
2
3
4
5

6
7
8
9
10
11
12





-
+






<?xml version="1.0"?>
<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.89.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.90.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
    </DbProviderFactories>
  </system.data>
  <connectionStrings>
    <add name="northwindEFEntities" connectionString="metadata=res://*/NorthwindModel2012.csdl|res://*/NorthwindModel2012.ssdl|res://*/NorthwindModel2012.msl;provider=System.Data.SQLite;provider connection string=&quot;data source=.\northwindEF.db&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>
Changes to testlinq/Properties/AssemblyInfo.cs.
37
38
39
40
41
42
43
44
45


37
38
39
40
41
42
43


44
45







-
-
+
+
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.89.0")]
[assembly: AssemblyFileVersion("1.0.89.0")]
[assembly: AssemblyVersion("1.0.90.0")]
[assembly: AssemblyFileVersion("1.0.90.0")]
Changes to tools/install/Properties/AssemblyInfo.cs.
24
25
26
27
28
29
30
31
32


24
25
26
27
28
29
30


31
32







-
-
+
+
// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.89.0")]
[assembly: AssemblyFileVersion("1.0.89.0")]
[assembly: AssemblyVersion("1.0.90.0")]
[assembly: AssemblyFileVersion("1.0.90.0")]
Changes to www/downloads.wiki.
78
79
80
81
82
83
84


























85
86
87
88
89
90
91
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







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







        as we do not necessarily have any knowledge of the other projects that
        use the same (or a similar) name.  That being said, if a particular
        question is related to the core SQLite native library itself, one of the
        <a href="http://www.sqlite.org/support.html">SQLite support options</a>
        is probably the best way to get an answer.
      </td>
    </tr>

    <tr bgcolor="#fff1c8">
      <td colspan="3" class="importantHeader">
        <b>Windows Embedded Compact</b>
      </td>
    </tr>

    <tr bgcolor="#fff1c8">
      <td colspan="3" class="importantNotes">
        Further information on integrating SQLite into Windows Embedded Compact
        can be found at the following web site:
      </td>
    </tr>

    <tr bgcolor="#fff1c8">
      <td class="importantNotes">
        &nbsp;
      </td>
      <td class="importantNotes" align="center">
        <a href="https://cesqlite2013.codeplex.com/">SQLite for Windows
        Embedded Compact 2013</a>
      </td>
      <td class="importantNotes">
        &nbsp;
      </td>
    </tr>
  </table>

  <table width="100%" cellpadding="5">
    <tr>
      <td colspan="3" class="importantHeader">
        <b>Package Types</b>
      </td>
319
320
321
322
323
324
325
326

327
328

329
330
331
332
333

334
335

336
337
338
339
340
341
342
343
344
345
346
347
348

349
350

351
352
353
354
355
356

357
358
359
360
361
362
363

364
365
366
367
368
369
370

371
372

373
374
375
376
377
378


379
380
381

382
383
384
385
386
387
388
389
390
391
392
393
394

395
396

397
398
399
400
401
402

403
404
405
406

407
408
409
410
411
412
413

414
415

416
417
418
419
420
421


422
423
424

425
426
427
428
429
430
431
432
433
434
435
436
437

438
439

440
441
442
443
444
445

446
447
448
449
450
451
452

453
454
455
456
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
739
740
741
742
743

744
745

746
747
748
749
750
751


752
753
754

755
756
757
758
759
760
761

762
763

764
765
766
767
768

769
770
771

772
773
774
775
776
777
778
779
780
781
782
783
784

785
786

787
788
789
790
791
792


793
794
795

796
797
798
799
800
801
802

803
804

805
806
807
808
809

810
811
812

813
814
815
816
817
818
819
820
821
822
823
824
825

826
827

828
829
830
831
832
833


834
835
836

837
838
839
840
841
842
843

844
845

846
847
848
849
850

851
852
853

854
855
856
857
858
859
860
861
862
863
864
865
866

867
868

869
870
871
872
873
874


875
876
877

878
879
880
881
882
883
884

885
886

887
888
889
890
891

892
893
894

895
896
897
898
899
900
901
902
903
904
905
906
907

908
909

910
911
912
913
914
915


916
917
918

919
920
921
922
923
924
925

926
927

928
929
930
931
932

933
934
935

936
937
938
939
940
941
942
943
944
945
946
947
948

949
950

951
952
953
954
955
956


957
958
959

960
961
962
963
964
965
966

967
968

969
970
971
972
973
974


975
976

977
978
979
980
981
982
983
984
985
986
987
988
989

990
991

992
993
994
995
996
997


998
999
1000

1001
1002
1003
1004
1005
1006
1007

1008
1009

1010
1011
1012
1013
1014
1015


1016
1017

1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
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
1069
1070
1071
1072

1073
1074

1075
1076
1077
1078
1079
1080


1081
1082
1083

1084
1085
1086
1087
1088
1089
1090

1091
1092

1093
1094
1095
1096
1097

1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114

1115
1116

1117
1118
1119
1120
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
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
1202
1203
1204
1205
1206


1207
1208
1209

1210
1211
1212
1213
1214
1215
1216

1217
1218

1219
1220
1221
1222
1223

1224
1225
1226
1227

1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240

1241
1242

1243
1244
1245
1246
1247
1248


1249
1250
1251

1252
1253
1254
1255
1256
1257
1258

1259
1260

1261
1262
1263
1264
1265

1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282

1283
1284

1285
1286
1287
1288
1289
1290


1291
1292
1293

1294
1295
1296
1297
1298
1299
1300

1301
1302

1303
1304
1305
1306
1307
1308


1309
1310
1311

1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324

1325
1326

1327
1328
1329
1330
1331
1332


1333
1334
1335

1336
1337
1338
1339
1340
1341
1342

1343
1344

1345
1346
1347
1348
1349
1350


1351
1352
1353

1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366

1367
1368

1369
1370
1371
1372
1373

1374
1375
1376

1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389

1390
1391

1392
1393
1394
1395
1396

1397
1398
1399
1400
1401

1402
1403
1404
1405
1406
1407
1408

1409
1410

1411
1412
1413
1414
1415

1416
1417
1418
1419
1420
1421
1422
1423

1424
1425
1426
1427
1428
1429
1430

1431
1432

1433
1434
1435
1436
1437

1438
1439
1440
1441
1442

1443
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
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

739
740
741
742
743
744
745

746
747

748
749
750
751
752

753
754
755

756
757
758
759
760
761
762
763
764
765
766
767
768

769
770

771
772
773
774
775


776
777
778
779

780
781
782
783
784
785
786

787
788

789
790
791
792
793

794
795
796

797
798
799
800
801
802
803
804
805
806
807
808
809

810
811

812
813
814
815
816


817
818
819
820

821
822
823
824
825
826
827

828
829

830
831
832
833
834

835
836
837

838
839
840
841
842
843
844
845
846
847
848
849
850

851
852

853
854
855
856
857


858
859
860
861

862
863
864
865
866
867
868

869
870

871
872
873
874
875

876
877
878

879
880
881
882
883
884
885
886
887
888
889
890
891

892
893

894
895
896
897
898


899
900
901
902

903
904
905
906
907
908
909

910
911

912
913
914
915
916

917
918
919

920
921
922
923
924
925
926
927
928
929
930
931
932

933
934

935
936
937
938
939


940
941
942
943

944
945
946
947
948
949
950

951
952

953
954
955
956
957

958
959
960

961
962
963
964
965
966
967
968
969
970
971
972
973

974
975

976
977
978
979
980


981
982
983
984

985
986
987
988
989
990
991

992
993

994
995
996
997
998


999
1000
1001

1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

1015
1016

1017
1018
1019
1020
1021


1022
1023
1024
1025

1026
1027
1028
1029
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
1069
1070
1071
1072
1073

1074
1075

1076
1077
1078
1079
1080

1081
1082
1083
1084

1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097

1098
1099

1100
1101
1102
1103
1104


1105
1106
1107
1108

1109
1110
1111
1112
1113
1114
1115

1116
1117

1118
1119
1120
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
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

1202
1203
1204
1205
1206

1207
1208
1209
1210

1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223

1224
1225

1226
1227
1228
1229
1230


1231
1232
1233
1234

1235
1236
1237
1238
1239
1240
1241

1242
1243

1244
1245
1246
1247
1248

1249
1250
1251
1252

1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265

1266
1267

1268
1269
1270
1271
1272


1273
1274
1275
1276

1277
1278
1279
1280
1281
1282
1283

1284
1285

1286
1287
1288
1289
1290

1291
1292
1293
1294

1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307

1308
1309

1310
1311
1312
1313
1314


1315
1316
1317
1318

1319
1320
1321
1322
1323
1324
1325

1326
1327

1328
1329
1330
1331
1332


1333
1334
1335
1336

1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349

1350
1351

1352
1353
1354
1355
1356


1357
1358
1359
1360

1361
1362
1363
1364
1365
1366
1367

1368
1369

1370
1371
1372
1373
1374


1375
1376
1377
1378

1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391

1392
1393

1394
1395
1396
1397
1398

1399
1400
1401

1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414

1415
1416

1417
1418
1419
1420
1421

1422
1423
1424
1425
1426

1427
1428
1429
1430
1431
1432
1433

1434
1435

1436
1437
1438
1439
1440

1441
1442
1443
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

1477
1478
1479
1480
1481

1482
1483
1484
1485
1486

1487
1488
1489
1490
1491
1492
1493
1494







-
+

-
+




-
+

-
+












-
+

-
+





-
+






-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+





-
+



-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+





-
+






-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+





-
+



-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+





-
+





-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+





-
+


-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+





-
-
+
+





-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+





-
-
+
+


-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+


-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+


-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+


-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+


-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+


-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+


-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
-
+
+

-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
-
+
+

-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+



-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+



-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+



-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+



-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+



-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+



-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+




-
+


-
+












-
+

-
+




-
+




-
+






-
+

-
+




-
+







-
+






-
+

-
+




-
+




-
+






-
+

-
+




-
+




-
+







        <b>Source Code</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx-source-1.0.88.0.zip">sqlite-netFx-source-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx-source-1.0.89.0.zip">sqlite-netFx-source-1.0.89.0.zip</a>
        <br />
        (3.20 MiB)
        (3.27 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This ZIP archive contains all current source code for System.Data.SQLite
        1.0.88.0 (3.7.17) combined into a single archive file.
        1.0.89.0 (3.8.1) combined into a single archive file.
        <br />
        (sha1: 9fd88303b867401c27f858b46b11b2e65c92557f)
        (sha1: 61cae071506f264a105aaa220fb19708634692c6)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 32-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-setup-bundle-x86-2005-1.0.88.0.exe">sqlite-netFx20-setup-bundle-x86-2005-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-setup-bundle-x86-2005-1.0.89.0.exe">sqlite-netFx20-setup-bundle-x86-2005-1.0.89.0.exe</a>
        <br />
        (4.33 MiB)
        (4.37 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x86 version of
        the System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2005
        the System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2005
        SP1 runtime for x86 is included.  The .NET Framework 2.0 SP2 is
        required.
        <br />
        <big><b>This is the only setup package that is capable of installing the
        design-time components for Visual Studio 2005.</b></big>
        <br />
        (sha1: 9a94f6072e6ffeeee81c11ced2df92e5c92208ce)
        (sha1: 51960fad6b51717827194a80bf0bae412e6de0f4)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-setup-x86-2005-1.0.88.0.exe">sqlite-netFx20-setup-x86-2005-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-setup-x86-2005-1.0.89.0.exe">sqlite-netFx20-setup-x86-2005-1.0.89.0.exe</a>
        <br />
        (4.32 MiB)
        (4.36 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2005 SP1 runtime for x86 is included.
        dependencies for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2005 SP1 runtime for x86 is included.
        The .NET Framework 2.0 SP2 is required.
        <br />
        (sha1: c9a7eabbda1cb0141172b413016964e55b5cfb80)
        (sha1: 7edc068b157e1aaadf71265f24e0523f0fd7acb3)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 64-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-setup-bundle-x64-2005-1.0.88.0.exe">sqlite-netFx20-setup-bundle-x64-2005-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-setup-bundle-x64-2005-1.0.89.0.exe">sqlite-netFx20-setup-bundle-x64-2005-1.0.89.0.exe</a>
        <br />
        (4.90 MiB)
        (4.95 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x64 version of
        the System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2005
        the System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2005
        SP1 runtime for x64 is included.  The .NET Framework 2.0 SP2 is
        required.
        <br />
        (sha1: cdd5b814773ca0d7e49e8ed02507aef51c3e0b9c)
        (sha1: 101e76531d5707c66ae9775871b9b964785a5a53)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-setup-x64-2005-1.0.88.0.exe">sqlite-netFx20-setup-x64-2005-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-setup-x64-2005-1.0.89.0.exe">sqlite-netFx20-setup-x64-2005-1.0.89.0.exe</a>
        <br />
        (4.89 MiB)
        (4.94 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2005 SP1 runtime for x64 is included.
        dependencies for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2005 SP1 runtime for x64 is included.
        The .NET Framework 2.0 SP2 is required.
        <br />
        (sha1: f3f6877eeadfa5224772a39a0604763b85771af3)
        (sha1: 505294c78723676b8a0558c3b5b5a5f75c028423)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 32-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-setup-bundle-x86-2008-1.0.88.0.exe">sqlite-netFx35-setup-bundle-x86-2008-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-setup-bundle-x86-2008-1.0.89.0.exe">sqlite-netFx35-setup-bundle-x86-2008-1.0.89.0.exe</a>
        <br />
        (6.36 MiB)
        (6.40 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x86 version of
        the System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2008
        the System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2008
        SP1 runtime for x86 is included.  The .NET Framework 3.5 SP1 is
        required.
        <br />
        <big><b>This is the only setup package that is capable of installing the
        design-time components for Visual Studio 2008.</b></big>
        <br />
        (sha1: fe2638de9919a36f46b7d4ff6736a3cf1f93eeec)
        (sha1: 79b6e9408dd6b43d32dd6e7ec88e516490aef299)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-setup-x86-2008-1.0.88.0.exe">sqlite-netFx35-setup-x86-2008-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-setup-x86-2008-1.0.89.0.exe">sqlite-netFx35-setup-x86-2008-1.0.89.0.exe</a>
        <br />
        (6.35 MiB)
        (6.39 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2008 SP1 runtime for x86 is included.
        dependencies for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2008 SP1 runtime for x86 is included.
        The .NET Framework 3.5 SP1 is required.
        <br />
        (sha1: 195bb5672a2e8e81c3928aee991fef135858deae)
        (sha1: f6a2a51e6ea7329552baf6de5bd592e2ca01b5ff)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 64-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-setup-bundle-x64-2008-1.0.88.0.exe">sqlite-netFx35-setup-bundle-x64-2008-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-setup-bundle-x64-2008-1.0.89.0.exe">sqlite-netFx35-setup-bundle-x64-2008-1.0.89.0.exe</a>
        <br />
        (7.09 MiB)
        (7.13 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x64 version of
        the System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2008
        the System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2008
        SP1 runtime for x64 is included.  The .NET Framework 3.5 SP1 is
        required.
        <br />
        (sha1: 8a224b9395f2a58e6441021c4933c8f3ce79cccb)
        (sha1: 3bad2ae0481dc165df62196524a255c1b1a7819f)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-setup-x64-2008-1.0.88.0.exe">sqlite-netFx35-setup-x64-2008-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-setup-x64-2008-1.0.89.0.exe">sqlite-netFx35-setup-x64-2008-1.0.89.0.exe</a>
        <br />
        (7.08 MiB)
        (7.13 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2008 SP1 runtime for x64 is included.
        dependencies for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2008 SP1 runtime for x64 is included.
        The .NET Framework 3.5 SP1 is required.
        <br />
        (sha1: 90ec2a123fff62e7ddeba9f40db7a6873b74aa39)
        (sha1: 55e50fa200260bcbb0185e48a8d2fd0f2ddd44e9)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 32-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-setup-bundle-x86-2010-1.0.88.0.exe">sqlite-netFx40-setup-bundle-x86-2010-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-setup-bundle-x86-2010-1.0.89.0.exe">sqlite-netFx40-setup-bundle-x86-2010-1.0.89.0.exe</a>
        <br />
        (10.69 MiB)
        (10.73 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x86 version of
        the System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2010
        the System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2010
        SP1 runtime for x86 is included.  The .NET Framework 4.0 is required.
        <br />
        <big><b>This is the only setup package that is capable of installing the
        design-time components for Visual Studio 2010.</b></big>
        <br />
        (sha1: 667207900c5e2e52bec8c253fde38a208b17a539)
        (sha1: f0e021f72b4cee3eb5d559ed055c49dd2852a0ab)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-setup-x86-2010-1.0.88.0.exe">sqlite-netFx40-setup-x86-2010-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-setup-x86-2010-1.0.89.0.exe">sqlite-netFx40-setup-x86-2010-1.0.89.0.exe</a>
        <br />
        (10.68 MiB)
        (10.72 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2010 SP1 runtime for x86 is included.
        dependencies for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2010 SP1 runtime for x86 is included.
        The .NET Framework 4.0 is required.
        <br />
        (sha1: ef6d470a0a885f91f4a3a399919f6f960c17ef3a)
        (sha1: fbc106a70c6011af3dc7d1294ee84a535984da3d)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 64-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-setup-bundle-x64-2010-1.0.88.0.exe">sqlite-netFx40-setup-bundle-x64-2010-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-setup-bundle-x64-2010-1.0.89.0.exe">sqlite-netFx40-setup-bundle-x64-2010-1.0.89.0.exe</a>
        <br />
        (11.93 MiB)
        (11.98 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x64 version of
        the System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2010
        the System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2010
        SP1 runtime for x64 is included.  The .NET Framework 4.0 is required.
        <br />
        (sha1: 8d308a983f7cc3ffb0f2b487c333e0d76a60c089)
        (sha1: a32136716d789998d3014ea8e5d0af726c3701a4)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-setup-x64-2010-1.0.88.0.exe">sqlite-netFx40-setup-x64-2010-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-setup-x64-2010-1.0.89.0.exe">sqlite-netFx40-setup-x64-2010-1.0.89.0.exe</a>
        <br />
        (11.93 MiB)
        (11.97 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2010 SP1 runtime for x64 is included.
        dependencies for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2010 SP1 runtime for x64 is included.
        The .NET Framework 4.0 is required.
        <br />
        (sha1: 7f113ba933dc2efaf850cfde89348224e67d4959)
        (sha1: e20b0cd847f97300e956e569c7ad4e176064dae6)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 32-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-setup-bundle-x86-2012-1.0.88.0.exe">sqlite-netFx45-setup-bundle-x86-2012-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-setup-bundle-x86-2012-1.0.89.0.exe">sqlite-netFx45-setup-bundle-x86-2012-1.0.89.0.exe</a>
        <br />
        (8.08 MiB)
        (8.12 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x86 version of
        the System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2012
        Update 1 runtime for x86 is included.  The .NET Framework 4.5 is
        the System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2012
        Update 3 runtime for x86 is included.  The .NET Framework 4.5 is
        required.
        <br />
        <big><b>This is the only setup package that is capable of installing the
        design-time components for Visual Studio 2012.</b></big>
        <br />
        (sha1: d0a01fb99ad6f6ebd877b0fa7733985618dd4b69)
        (sha1: d8eb780a3554684d1ffc3fca767867dfa22fc407)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-setup-x86-2012-1.0.88.0.exe">sqlite-netFx45-setup-x86-2012-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-setup-x86-2012-1.0.89.0.exe">sqlite-netFx45-setup-x86-2012-1.0.89.0.exe</a>
        <br />
        (8.11 MiB)
        (8.15 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2012 Update 1 runtime for x86 is
        dependencies for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2012 Update 3 runtime for x86 is
        included.  The .NET Framework 4.5 is required.
        <br />
        (sha1: 2ceffa1f0184a3630d56973057671c1376c7a849)
        (sha1: a7ff3e421ceb8b911d38481d5e5dcb799b992e9b)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 64-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-setup-bundle-x64-2012-1.0.88.0.exe">sqlite-netFx45-setup-bundle-x64-2012-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-setup-bundle-x64-2012-1.0.89.0.exe">sqlite-netFx45-setup-bundle-x64-2012-1.0.89.0.exe</a>
        <br />
        (8.73 MiB)
        (8.77 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x64 version of
        the System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2012
        Update 1 runtime for x64 is included.  The .NET Framework 4.5 is
        the System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2012
        Update 3 runtime for x64 is included.  The .NET Framework 4.5 is
        required.
        <br />
        (sha1: a8b4d85b12a9159ae132892139550bfbbb01ebea)
        (sha1: d894b323ae8c9ca3b717832dc381ba50e58241cb)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-setup-x64-2012-1.0.88.0.exe">sqlite-netFx45-setup-x64-2012-1.0.88.0.exe</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-setup-x64-2012-1.0.89.0.exe">sqlite-netFx45-setup-x64-2012-1.0.89.0.exe</a>
        <br />
        (8.77 MiB)
        (8.82 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2012 Update 1 runtime for x64 is
        dependencies for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2012 Update 3 runtime for x64 is
        included.  The .NET Framework 4.5 is required.
        <br />
        (sha1: 963a222ee016c265e8de33c439ac1d8d052e43cd)
        (sha1: 8c10bb9228fe578c46c2a228622a26e0756dc645)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 32-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-binary-bundle-Win32-2005-1.0.88.0.zip">sqlite-netFx20-binary-bundle-Win32-2005-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-binary-bundle-Win32-2005-1.0.89.0.zip">sqlite-netFx20-binary-bundle-Win32-2005-1.0.89.0.zip</a>
        <br />
        (1.34 MiB)
        (1.37 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2005 SP1 runtime for x86 and the .NET
        the binaries for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2005 SP1 runtime for x86 and the .NET
        Framework 2.0 SP2 are required.
        <br />
        (sha1: f4d863dff1f5ed0530efd3065f3ad3d880ca707d)
        (sha1: f5c6e5e68da81eb99493eb93fcb1d12e98aa6337)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-binary-Win32-2005-1.0.88.0.zip">sqlite-netFx20-binary-Win32-2005-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-binary-Win32-2005-1.0.89.0.zip">sqlite-netFx20-binary-Win32-2005-1.0.89.0.zip</a>
        <br />
        (1.33 MiB)
        (1.36 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2005 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2005 SP1
        runtime for x86 and the .NET Framework 2.0 SP2 are required.
        <br />
        (sha1: 8f15a4f3338b48d693b91cc23f21471923d118de)
        (sha1: f7c246b571f91146dec1acd28cc0453619823076)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 64-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-binary-bundle-x64-2005-1.0.88.0.zip">sqlite-netFx20-binary-bundle-x64-2005-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-binary-bundle-x64-2005-1.0.89.0.zip">sqlite-netFx20-binary-bundle-x64-2005-1.0.89.0.zip</a>
        <br />
        (1.52 MiB)
        (1.56 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2005 SP1 runtime for x64 and the .NET
        the binaries for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2005 SP1 runtime for x64 and the .NET
        Framework 2.0 SP2 are required.
        <br />
        (sha1: 6a8c994da059a3152bd1e1f88120b262c61b1020)
        (sha1: e5cfe5e5306e3d1437d1c4b96cd6164e0c14b9da)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-binary-x64-2005-1.0.88.0.zip">sqlite-netFx20-binary-x64-2005-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-binary-x64-2005-1.0.89.0.zip">sqlite-netFx20-binary-x64-2005-1.0.89.0.zip</a>
        <br />
        (1.51 MiB)
        (1.56 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2005 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2005 SP1
        runtime for x64 and the .NET Framework 2.0 SP2 are required.
        <br />
        (sha1: 6cf8f62a9e22f2b9854b83f9ca61f2f4c6c05868)
        (sha1: b2d623f88bde71c197df3e81155556d990ba1d4e)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 32-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-binary-bundle-Win32-2008-1.0.88.0.zip">sqlite-netFx35-binary-bundle-Win32-2008-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-binary-bundle-Win32-2008-1.0.89.0.zip">sqlite-netFx35-binary-bundle-Win32-2008-1.0.89.0.zip</a>
        <br />
        (1.78 MiB)
        (1.81 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2008 SP1 runtime for x86 and the .NET
        the binaries for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2008 SP1 runtime for x86 and the .NET
        Framework 3.5 SP1 are required.
        <br />
        (sha1: e7df4e81a2d4726fe635cf1d213c17d4f221e3d2)
        (sha1: 0d29748396369c4b5b211e8c3519b534f93ee24d)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-binary-Win32-2008-1.0.88.0.zip">sqlite-netFx35-binary-Win32-2008-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-binary-Win32-2008-1.0.89.0.zip">sqlite-netFx35-binary-Win32-2008-1.0.89.0.zip</a>
        <br />
        (1.77 MiB)
        (1.80 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2008 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2008 SP1
        runtime for x86 and the .NET Framework 3.5 SP1 are required.
        <br />
        (sha1: d73e88767652d34b04468dda101669a259d39609)
        (sha1: a531b6ef7b68996d9c8acb9cf2d2235bd0c99317)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 64-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-binary-bundle-x64-2008-1.0.88.0.zip">sqlite-netFx35-binary-bundle-x64-2008-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-binary-bundle-x64-2008-1.0.89.0.zip">sqlite-netFx35-binary-bundle-x64-2008-1.0.89.0.zip</a>
        <br />
        (1.85 MiB)
        (1.88 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2008 SP1 runtime for x64 and the .NET
        the binaries for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2008 SP1 runtime for x64 and the .NET
        Framework 3.5 SP1 are required.
        <br />
        (sha1: 1863cc4997a3d6552e1cefbaf233c99b15a22428)
        (sha1: f0d3ed63f56e311923bf7b00153240fdcd322442)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-binary-x64-2008-1.0.88.0.zip">sqlite-netFx35-binary-x64-2008-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-binary-x64-2008-1.0.89.0.zip">sqlite-netFx35-binary-x64-2008-1.0.89.0.zip</a>
        <br />
        (1.84 MiB)
        (1.87 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2008 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2008 SP1
        runtime for x64 and the .NET Framework 3.5 SP1 are required.
        <br />
        (sha1: 617f754228a3288f61349f32deb1271868789098)
        (sha1: c670327f2f9d131e9b69212878e609de8e9d3503)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 32-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-binary-bundle-Win32-2010-1.0.88.0.zip">sqlite-netFx40-binary-bundle-Win32-2010-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-binary-bundle-Win32-2010-1.0.89.0.zip">sqlite-netFx40-binary-bundle-Win32-2010-1.0.89.0.zip</a>
        <br />
        (1.83 MiB)
        (1.87 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2010 SP1 runtime for x86 and the .NET
        the binaries for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2010 SP1 runtime for x86 and the .NET
        Framework 4.0 are required.
        <br />
        (sha1: 8e1a01415b492f959597b23bfbf9cd6e80cd1f84)
        (sha1: 63fc63a074525084ec5bac7b61abe4fc4fe1b1f6)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-binary-Win32-2010-1.0.88.0.zip">sqlite-netFx40-binary-Win32-2010-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-binary-Win32-2010-1.0.89.0.zip">sqlite-netFx40-binary-Win32-2010-1.0.89.0.zip</a>
        <br />
        (1.83 MiB)
        (1.86 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2010 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2010 SP1
        runtime for x86 and the .NET Framework 4.0 are required.
        <br />
        (sha1: 35bce887ccf19728f088ee12ee063d2f1bb32a1b)
        (sha1: 31aed3a9207443a28c8d35692799dcbdc5d3e07e)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 64-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-binary-bundle-x64-2010-1.0.88.0.zip">sqlite-netFx40-binary-bundle-x64-2010-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-binary-bundle-x64-2010-1.0.89.0.zip">sqlite-netFx40-binary-bundle-x64-2010-1.0.89.0.zip</a>
        <br />
        (1.85 MiB)
        (1.88 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2010 SP1 runtime for x64 and the .NET
        the binaries for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2010 SP1 runtime for x64 and the .NET
        Framework 4.0 are required.
        <br />
        (sha1: e8796d30134e04629eb54bc2f317b11693a74ea7)
        (sha1: da620e26f1c05509ecee1d7bf71ccf1342dd8284)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-binary-x64-2010-1.0.88.0.zip">sqlite-netFx40-binary-x64-2010-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-binary-x64-2010-1.0.89.0.zip">sqlite-netFx40-binary-x64-2010-1.0.89.0.zip</a>
        <br />
        (1.85 MiB)
        (1.88 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2010 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2010 SP1
        runtime for x64 and the .NET Framework 4.0 are required.
        <br />
        (sha1: f07c83a7dd9d8aaccd025188ba2685d7dbbf86a4)
        (sha1: 33089a091e51be4d06ac53eb0a9f94e3e5498d48)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 32-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-binary-bundle-Win32-2012-1.0.88.0.zip">sqlite-netFx45-binary-bundle-Win32-2012-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-binary-bundle-Win32-2012-1.0.89.0.zip">sqlite-netFx45-binary-bundle-Win32-2012-1.0.89.0.zip</a>
        <br />
        (1.76 MiB)
        (1.79 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2012 Update 1 runtime for x86 and
        the binaries for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2012 Update 3 runtime for x86 and
        the .NET Framework 4.5 are required.
        <br />
        (sha1: 41333bbe3055b1279350ce4233c7347b88f13427)
        (sha1: 4ff9f4baf886cc8568209c1264dbfea11b947160)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-binary-Win32-2012-1.0.88.0.zip">sqlite-netFx45-binary-Win32-2012-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-binary-Win32-2012-1.0.89.0.zip">sqlite-netFx45-binary-Win32-2012-1.0.89.0.zip</a>
        <br />
        (1.81 MiB)
        (1.84 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2012
        Update 1 runtime for x86 and the .NET Framework 4.5 are required.
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2012
        Update 3 runtime for x86 and the .NET Framework 4.5 are required.
        <br />
        (sha1: 3782443d25a3a03fd2dbcacce9ab2959fc861135)
        (sha1: ec06b675463690aaf3b841199cfe092ef764d0ad)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 64-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-binary-bundle-x64-2012-1.0.88.0.zip">sqlite-netFx45-binary-bundle-x64-2012-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-binary-bundle-x64-2012-1.0.89.0.zip">sqlite-netFx45-binary-bundle-x64-2012-1.0.89.0.zip</a>
        <br />
        (1.79 MiB)
        (1.82 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2012 Update 1 runtime for x64 and
        the binaries for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2012 Update 3 runtime for x64 and
        the .NET Framework 4.5 are required.
        <br />
        (sha1: ed7fba1fc615b4153b507d25f61ed087f347fba3)
        (sha1: 8cfbb81be6ca9facf3f7ed0288285205571fb81f)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-binary-x64-2012-1.0.88.0.zip">sqlite-netFx45-binary-x64-2012-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-binary-x64-2012-1.0.89.0.zip">sqlite-netFx45-binary-x64-2012-1.0.89.0.zip</a>
        <br />
        (1.86 MiB)
        (1.89 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2012
        Update 1 runtime for x64 and the .NET Framework 4.5 are required.
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2012
        Update 3 runtime for x64 and the .NET Framework 4.5 are required.
        <br />
        (sha1: d2364c467df23f691602da57790c963ec3e56f39)
        (sha1: a6079d1af1a7b7f8a45aefbb7d7f32b7e5214bca)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 32-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-static-binary-bundle-Win32-2005-1.0.88.0.zip">sqlite-netFx20-static-binary-bundle-Win32-2005-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-static-binary-bundle-Win32-2005-1.0.89.0.zip">sqlite-netFx20-static-binary-bundle-Win32-2005-1.0.89.0.zip</a>
        <br />
        (1.54 MiB)
        (1.58 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2005 SP1 runtime for x86 is statically
        the binaries for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2005 SP1 runtime for x86 is statically
        linked.  The .NET Framework 2.0 SP2 is required.
        <br />
        (sha1: 76635459de385d0c05e4503ef01d1c5d3cb06a7a)
        (sha1: cdab73a18f9e99e56d58e7f73da85a8ff0c119d9)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-static-binary-Win32-2005-1.0.88.0.zip">sqlite-netFx20-static-binary-Win32-2005-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-static-binary-Win32-2005-1.0.89.0.zip">sqlite-netFx20-static-binary-Win32-2005-1.0.89.0.zip</a>
        <br />
        (1.54 MiB)
        (1.57 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2005 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2005 SP1
        runtime for x86 is statically linked.  The .NET Framework 2.0 SP2 is
        required.
        <br />
        (sha1: 4e0f25c447782d988fa0f6e046c67119eb05bff0)
        (sha1: c7104780c97dce9ba377634123ce49a6c4d7af66)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 64-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-static-binary-bundle-x64-2005-1.0.88.0.zip">sqlite-netFx20-static-binary-bundle-x64-2005-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-static-binary-bundle-x64-2005-1.0.89.0.zip">sqlite-netFx20-static-binary-bundle-x64-2005-1.0.89.0.zip</a>
        <br />
        (1.68 MiB)
        (1.71 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2005 SP1 runtime for x64 is statically
        the binaries for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2005 SP1 runtime for x64 is statically
        linked.  The .NET Framework 2.0 SP2 is required.
        <br />
        (sha1: 028f2e001712d0f4f893d30f97176d2500a42e6d)
        (sha1: 9e72e049ae51529de53ee113ea4b63320287f1f5)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx20-static-binary-x64-2005-1.0.88.0.zip">sqlite-netFx20-static-binary-x64-2005-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx20-static-binary-x64-2005-1.0.89.0.zip">sqlite-netFx20-static-binary-x64-2005-1.0.89.0.zip</a>
        <br />
        (1.67 MiB)
        (1.71 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2005 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2005 SP1
        runtime for x64 is statically linked.  The .NET Framework 2.0 SP2 is
        required.
        <br />
        (sha1: f4520dd09c6e5be6efb97ac43d0d784cb58ca420)
        (sha1: e475705f290249753af2d004719285f1b3686332)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 32-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.88.0.zip">sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.89.0.zip">sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.89.0.zip</a>
        <br />
        (1.99 MiB)
        (2.02 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2008 SP1 runtime for x86 is statically
        the binaries for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2008 SP1 runtime for x86 is statically
        linked.  The .NET Framework 3.5 SP1 is required.
        <br />
        (sha1: 69884ce857ea8e307807445bbf28e4f4ea7138c7)
        (sha1: 4deead936f31943ace38d94cb748f9cede9cf3d0)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-static-binary-Win32-2008-1.0.88.0.zip">sqlite-netFx35-static-binary-Win32-2008-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-static-binary-Win32-2008-1.0.89.0.zip">sqlite-netFx35-static-binary-Win32-2008-1.0.89.0.zip</a>
        <br />
        (1.99 MiB)
        (2.02 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2008 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2008 SP1
        runtime for x86 is statically linked.  The .NET Framework 3.5 SP1 is
        required.
        <br />
        (sha1: 7d2653a81f334e2478202174a3188e170ce34bfe)
        (sha1: 304f231fe3f890827cbaf5badf9848763d2db554)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 64-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-static-binary-bundle-x64-2008-1.0.88.0.zip">sqlite-netFx35-static-binary-bundle-x64-2008-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-static-binary-bundle-x64-2008-1.0.89.0.zip">sqlite-netFx35-static-binary-bundle-x64-2008-1.0.89.0.zip</a>
        <br />
        (2.02 MiB)
        (2.06 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2008 SP1 runtime for x64 is statically
        the binaries for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2008 SP1 runtime for x64 is statically
        linked.  The .NET Framework 3.5 SP1 is required.
        <br />
        (sha1: f7abf287b554b1688760758a409a5909e1b831d3)
        (sha1: 63509b29a7e83b096e470b561ba93a8dd74871d9)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-static-binary-x64-2008-1.0.88.0.zip">sqlite-netFx35-static-binary-x64-2008-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-static-binary-x64-2008-1.0.89.0.zip">sqlite-netFx35-static-binary-x64-2008-1.0.89.0.zip</a>
        <br />
        (2.02 MiB)
        (2.05 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2008 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2008 SP1
        runtime for x64 is statically linked.  The .NET Framework 3.5 SP1 is
        required.
        <br />
        (sha1: 99cbad37ec9759a0193185ea608402851c85a607)
        (sha1: 3e0176132a9cd8db6ca219ae7013d45b8f07f51f)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 32-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.88.0.zip">sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.89.0.zip">sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.89.0.zip</a>
        <br />
        (2.05 MiB)
        (2.08 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2010 SP1 runtime for x86 is statically
        the binaries for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2010 SP1 runtime for x86 is statically
        linked.  The .NET Framework 4.0 is required.
        <br />
        (sha1: 6d20c54b1092aed213f34cb3f450bf9e1bd9cdbe)
        (sha1: 5fdadb9771555ff1340bb2f3e4d10c2a3db1b242)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-static-binary-Win32-2010-1.0.88.0.zip">sqlite-netFx40-static-binary-Win32-2010-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-static-binary-Win32-2010-1.0.89.0.zip">sqlite-netFx40-static-binary-Win32-2010-1.0.89.0.zip</a>
        <br />
        (2.04 MiB)
        (2.07 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2010 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2010 SP1
        runtime for x86 is statically linked.  The .NET Framework 4.0 is
        required.
        <br />
        (sha1: 9d0a9dff7d66f860f540caa9799e75da29b44b5b)
        (sha1: 790ac77ff205095b85f1a9ec9e36fe5499b2c425)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 64-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-static-binary-bundle-x64-2010-1.0.88.0.zip">sqlite-netFx40-static-binary-bundle-x64-2010-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-static-binary-bundle-x64-2010-1.0.89.0.zip">sqlite-netFx40-static-binary-bundle-x64-2010-1.0.89.0.zip</a>
        <br />
        (2.05 MiB)
        (2.08 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2010 SP1 runtime for x64 is statically
        the binaries for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2010 SP1 runtime for x64 is statically
        linked.  The .NET Framework 4.0 is required.
        <br />
        (sha1: 3aaccefeb3b7953423f32de0fedfc1e7a778c0f4)
        (sha1: a72b4e652f7dab0ef80eaae99973c94f4b93bb40)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx40-static-binary-x64-2010-1.0.88.0.zip">sqlite-netFx40-static-binary-x64-2010-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx40-static-binary-x64-2010-1.0.89.0.zip">sqlite-netFx40-static-binary-x64-2010-1.0.89.0.zip</a>
        <br />
        (2.04 MiB)
        (2.07 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2010 SP1
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2010 SP1
        runtime for x64 is statically linked.  The .NET Framework 4.0 is
        required.
        <br />
        (sha1: 3ae44bad6730d75f62181b6f0286a2b7eaeb8f90)
        (sha1: aa77ecd69800a1299477028ec52abee945a059ab)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 32-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-static-binary-bundle-Win32-2012-1.0.88.0.zip">sqlite-netFx45-static-binary-bundle-Win32-2012-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-static-binary-bundle-Win32-2012-1.0.89.0.zip">sqlite-netFx45-static-binary-bundle-Win32-2012-1.0.89.0.zip</a>
        <br />
        (2.09 MiB)
        (2.12 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2012 Update 1 runtime for x86 is
        the binaries for the x86 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2012 Update 3 runtime for x86 is
        statically linked.  The .NET Framework 4.5 is required.
        <br />
        (sha1: 84357f9bac730bad2cdf7de133340a2139e93588)
        (sha1: 200f07f317b005c9b9672afc9b363c7b939e4ecb)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-static-binary-Win32-2012-1.0.88.0.zip">sqlite-netFx45-static-binary-Win32-2012-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-static-binary-Win32-2012-1.0.89.0.zip">sqlite-netFx45-static-binary-Win32-2012-1.0.89.0.zip</a>
        <br />
        (2.13 MiB)
        (2.16 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2012
        Update 1 runtime for x86 is statically linked.  The .NET Framework 4.5
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2012
        Update 3 runtime for x86 is statically linked.  The .NET Framework 4.5
        is required.
        <br />
        (sha1: 1d94d5c5f902a1f2cf6ccc91af29ee42db62c2f6)
        (sha1: ea3d198d880c33fc8f617db2a3ca1308b21ba449)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 64-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-static-binary-bundle-x64-2012-1.0.88.0.zip">sqlite-netFx45-static-binary-bundle-x64-2012-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-static-binary-bundle-x64-2012-1.0.89.0.zip">sqlite-netFx45-static-binary-bundle-x64-2012-1.0.89.0.zip</a>
        <br />
        (2.05 MiB)
        (2.08 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.88.0
        (3.7.17) package.  The Visual C++ 2012 Update 1 runtime for x64 is
        the binaries for the x64 version of the System.Data.SQLite 1.0.89.0
        (3.8.1) package.  The Visual C++ 2012 Update 3 runtime for x64 is
        statically linked.  The .NET Framework 4.5 is required.
        <br />
        (sha1: 4e41c7b0dd7acd5df89c56eae2946fc34d3163a6)
        (sha1: 30aa93a1b8f63215acd133e36a8ee6fd2d81e21d)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx45-static-binary-x64-2012-1.0.88.0.zip">sqlite-netFx45-static-binary-x64-2012-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx45-static-binary-x64-2012-1.0.89.0.zip">sqlite-netFx45-static-binary-x64-2012-1.0.89.0.zip</a>
        <br />
        (2.12 MiB)
        (2.15 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.88.0 (3.7.17) package.  The Visual C++ 2012
        Update 1 runtime for x64 is statically linked.  The .NET Framework 4.5
        System.Data.SQLite 1.0.89.0 (3.8.1) package.  The Visual C++ 2012
        Update 3 runtime for x64 is statically linked.  The .NET Framework 4.5
        is required.
        <br />
        (sha1: 081547e365414520d58ed43e258acc7bca5da817)
        (sha1: d6833fecbd18158cc8c842f612d78580d5c338fe)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for Windows CE (.NET Compact Framework 3.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.88.0/sqlite-netFx35-binary-PocketPC-ARM-2008-1.0.88.0.zip">sqlite-netFx35-binary-PocketPC-ARM-2008-1.0.88.0.zip</a>
        <a href="/downloads/1.0.89.0/sqlite-netFx35-binary-PocketPC-ARM-2008-1.0.89.0.zip">sqlite-netFx35-binary-PocketPC-ARM-2008-1.0.89.0.zip</a>
        <br />
        (0.98 MiB)
        (1.01 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the PocketPC version
        of the System.Data.SQLite 1.0.88.0 (3.7.17) package.  The .NET Compact
        of the System.Data.SQLite 1.0.89.0 (3.8.1) package.  The .NET Compact
        Framework 3.5 is required.
        <br />
        (sha1: bd874a4536b98033aec602fc5b67de39bd2d447c)
        (sha1: bb812fa516ff21f41b9104e6f85f5e2ae6e619de)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Official NuGet Packages</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite/1.0.88.0">System.Data.SQLite.1.0.88.0.nupkg</a>
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite/1.0.89.0">System.Data.SQLite.1.0.89.0.nupkg</a>
        <br />
        (3.29 MiB)
        (3.59 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This NuGet package contains all the binaries for both the x86 and x64
        versions of System.Data.SQLite 1.0.88.0 (3.7.17).  The .NET Framework
        versions of System.Data.SQLite 1.0.89.0 (3.8.1).  The .NET Framework
        3.5 SP1, 4.0, or 4.5 is required.  For the included native binaries, the
        version of the Visual C++ runtime corresponding to the .NET Framework
        used by the associated managed assembly is statically linked.
        <br />
        (sha1: e2734031fa48ae20878dfa93e48118f2156ac01b)
        (sha1: a95a465bc6c583377c5e117fd1d87c95444e32de)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.MSIL/1.0.88.0">System.Data.SQLite.MSIL.1.0.88.0.nupkg</a>
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.MSIL/1.0.89.0">System.Data.SQLite.MSIL.1.0.89.0.nupkg</a>
        <br />
        (0.38 MiB)
        (0.60 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This NuGet package contains the managed binaries for System.Data.SQLite
        1.0.88.0.  The .NET Framework 3.5 SP1, 4.0, or 4.5 is required.
        1.0.89.0.  The .NET Framework 3.5 SP1, 4.0, or 4.5 is required.
        <br />
        <big><b>This NuGet package does not include any code from the native
        SQLite core library and will not work properly without the native
        assembly &quot;SQLite.Interop.dll&quot; compiled for the processor
        architecture of the host process being present in a directory in the
        native library search path.</b></big>
        <br />
        (sha1: 31ca66e40a5b2ca07a5a812062c33997f66b5164)
        (sha1: 26363f2c29fd3320e0bde30dafe9baaed64774e4)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.x86/1.0.88.0">System.Data.SQLite.x86.1.0.88.0.nupkg</a>
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.x86/1.0.89.0">System.Data.SQLite.x86.1.0.89.0.nupkg</a>
        <br />
        (1.67 MiB)
        (1.92 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This NuGet package contains all the binaries for the x86 version of
        System.Data.SQLite 1.0.88.0 (3.7.17).  The .NET Framework 3.5 SP1,
        System.Data.SQLite 1.0.89.0 (3.8.1).  The .NET Framework 3.5 SP1,
        4.0, or 4.5 is required.  For the included native binaries, the version
        of the Visual C++ runtime corresponding to the .NET Framework used by
        the associated managed assembly is statically linked.
        <br />
        (sha1: a119b92fd2a643ea5c87adf123a452d4a9fc4a99)
        (sha1: 47d3200c456ff4f98a1d9ea163c96791dd540c83)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.x64/1.0.88.0">System.Data.SQLite.x64.1.0.88.0.nupkg</a>
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.x64/1.0.89.0">System.Data.SQLite.x64.1.0.89.0.nupkg</a>
        <br />
        (1.88 MiB)
        (2.14 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This NuGet package contains all the binaries for the x64 version of
        System.Data.SQLite 1.0.88.0 (3.7.17).  The .NET Framework 3.5 SP1,
        System.Data.SQLite 1.0.89.0 (3.8.1).  The .NET Framework 3.5 SP1,
        4.0, or 4.5 is required.  For the included native binaries, the version
        of the Visual C++ runtime corresponding to the .NET Framework used by
        the associated managed assembly is statically linked.
        <br />
        (sha1: 7f269a78a1f92604408ed5e335fab1d20e83cbef)
        (sha1: 73379f5ae93f0709ce353333a31dbc4f311140c7)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Legacy Versions</b>
      </td>
Changes to www/news.wiki.
1
2
3
4
5
6

7
8
9














10
11
12
13

14


15



16
17
18
19
20
21
22
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





-
+


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




+

+
+

+
+
+







<title>News</title>

<b>Version History</b>

<p>
    <b>1.0.89.0 - September XX, 2013 <font color="red">(release scheduled)</font></b>
    <b>1.0.90.0 - January XX, 2014 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Updated to [http://www.sqlite.org/src/info/trunk|SQLite 3.8.1].</li>
    <li>Updated to [http://www.sqlite.org/src/info/trunk|SQLite 3.8.2].</li>
    <li>Add experimental support for the native regexp extension.</li>
    <li>Never create a new connection wrapper in the SQLiteConnection.Shutdown method.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class.</li>
    <li>Add memory leak detection to the test project for the .NET Compact Framework.</li>
    <li>Add SQLITE_ENABLE_MEMORY_MANAGEMENT compile-time option to the interop assembly.</li>
    <li>Better handling of non-error log messages from the SQLite core library. Pursuant to [44df10ea90].</li>
</ul>
<p>
    <b>1.0.89.0 - October 28, 2013</b>
</p>
<ul>
    <li>Updated to [http://www.sqlite.org/releaselog/3_8_1.html|SQLite 3.8.1].</li>
    <li>Add AutoCommit property to the SQLiteConnection class. Fix for [9ba9346f75].</li>
    <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for [3113734605].</li>
    <li>Check the result of sqlite3_column_name function against NULL.</li>
    <li>Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.</li>
    <li>Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for [aba4549801].</li>
    <li>Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter.</li>
    <li>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Make sure the database cannot be changed by a query when the CommandBehavior.SchemaOnly flag is used. Fix for [f8dbab8baf].&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Fix bug in [http://sourceforge.net/projects/ndoc3|NDoc3] that was preventing some of the MSDN documentation links from working.</li>
    <li>Include the XML documentation files in the NuGet packages. Fix for [5970d5b0a6].</li>
    <li>Add InteropVersion, InteropSourceId, ProviderVersion, and ProviderSourceId properties to the SQLiteConnection class.</li>
    <li>Add experimental support for interfacing with the authorizer callback in the SQLite core library.</li>
    <li>Add experimental support for the native totype extension.</li>
</ul>
<p>
    <b>1.0.88.0 - August 7, 2013</b>
</p>
<ul>
    <li>Various fixes to managed virtual table integration infrastructure.</li>
    <li>Implement workaround for an incorrect PROCESSOR_ARCHITECTURE being reported. Fix for [9ac9862611].</li>